当前版本,在内建模块中增加了和base64编解码相关的模块函数,从而可以实现和base64编解码相关的功能。
页面导航:
zenglServer源代码的相关地址:https://github.com/zenglong/zenglServer 当前版本对应的tag标签为:v0.21.0
当前版本,在内建模块中增加了和base64编解码相关的模块函数,从而可以实现和base64编解码相关的功能。
bltBase64Encode模块函数,用于对数据进行base64解码,相关的C源码位于module_builtin.c文件中:
...................................................................... #include "base64.h" ...................................................................... /** * bltBase64Encode模块函数,对数据进行base64编码 * 第一个参数data必须是字符串,或者是整数类型的数据指针 * 第二个参数data_len是可选参数,当提供了该参数时,必须是整数类型,表示需要编码的data数据的尺寸大小,默认值是-1,表示自动检测data的尺寸大小 * 返回值是将data数据经过了base64编码后的字符串 * 例如: use builtin; def TRUE 1; encode_str = bltBase64Encode("hello world"); print encode_str; 上面脚本使用bltBase64Encode来对hello world字符串进行base64编码 use builtin; def TRUE 1; encode_str = bltBase64Encode("hello world", 4); print encode_str; 上面代码片段,在提供了第二个参数4后,就只会对hello world的前4个字符进行base64编码 use builtin,openssl; def RSA_PUBLIC 1; def RSA_PRIVATE 0; def DUMP_HEX 2; ................................................... key = read_rsa_key('rsa_public.key', RSA_PUBLIC); p_key = read_rsa_key('rsa_private.key', RSA_PRIVATE); print 'source string:' + (src_str = "hello world! I'm a programmer!") + br; enc_len = opensslPrivateEncrypt(src_str, -1, p_key, &enc); print 'encrypt: ' + bltDumpPtrData(enc, enc_len, DUMP_HEX) + br; print 'encrypt base64 encode: ' + (encode = bltBase64Encode(enc)) + br; 以上代码片段,通过将数据指针enc传递给bltBase64Encode,从而对openssl加密后的二进制数据进行base64编码 */ ZL_EXP_VOID module_builtin_base64_encode(ZL_EXP_VOID * VM_ARG, ZL_EXP_INT argcount) { ZENGL_EXPORT_MOD_FUN_ARG arg = {ZL_EXP_FAT_NONE,{0}}; const char * func_name = "bltBase64Encode"; if(argcount < 1) zenglApi_Exit(VM_ARG,"usage: %s(data[, data_len = -1]): string", func_name); zenglApi_GetFunArg(VM_ARG,1,&arg); if(arg.type != ZL_EXP_FAT_STR && arg.type != ZL_EXP_FAT_INT) { zenglApi_Exit(VM_ARG,"the first argument [data] of %s must be string or integer", func_name); } unsigned char * data = NULL; ZL_EXP_BOOL is_data_str = ZL_EXP_FALSE; MAIN_DATA * my_data = zenglApi_GetExtraData(VM_ARG, "my_data"); int data_ptr_size = 0; if(arg.type == ZL_EXP_FAT_STR) { data = (unsigned char *)arg.val.str; is_data_str = ZL_EXP_TRUE; } else { data = (unsigned char *)arg.val.integer; int ptr_idx = pointer_list_get_ptr_idx(&(my_data->pointer_list), data); if(ptr_idx < 0) { zenglApi_Exit(VM_ARG,"runtime error: the first argument [data] of %s is invalid pointer", func_name); } data_ptr_size = my_data->pointer_list.list[ptr_idx].ptr_size; } int data_len = -1; if(argcount > 1) { zenglApi_GetFunArg(VM_ARG,2,&arg); if(arg.type != ZL_EXP_FAT_INT) { zenglApi_Exit(VM_ARG,"the second argument [data_len] of %s must be integer", func_name); } data_len = (int)arg.val.integer; } if(data_len < 0) { if(is_data_str) { data_len = (int)strlen((char *)data); } else { data_len = data_ptr_size; } } if(data_ptr_size > 0 && data_len > data_ptr_size) { data_len = data_ptr_size; } if(data_len > 0) { unsigned int encode_len = b64e_size(data_len) + 1; unsigned char * encode_str = malloc((sizeof(char) * encode_len)); encode_len = b64_encode(data, (unsigned int)data_len, encode_str); zenglApi_SetRetVal(VM_ARG, ZL_EXP_FAT_STR, (char *)encode_str, 0, 0); free(encode_str); } else { zenglApi_SetRetVal(VM_ARG, ZL_EXP_FAT_STR, "", 0, 0); } }
bltBase64Decode模块函数,用于对数据进行base64解码,相关的C源码也位于module_builtin.c文件中:
/** * bltBase64Decode模块函数,对数据进行base64解码 * 第一个参数data表示需要解码的base64编码,必须是字符串类型 * 第二个参数result必须是引用类型,用于存储base64解码后的结果 * 第三个参数decode_to_str是可选的,必须是整数类型,表示是否将第二个result参数转为字符串类型,默认为0表示不转为字符串,因此,默认情况下,result存储的会是整数类型的数据指针 * 如果decode_to_str的值为1则result存储的会是字符串类型的结果 * 返回值表示result结果的字节长度 * 例如: use builtin; def TRUE 1; encode_str = bltBase64Encode("hello world"); print encode_str; decode_len = bltBase64Decode(encode_str, &decode, TRUE); print 'decode_len: ' + decode_len; print 'decode: ' + decode; 上面代码片段先将hello world字符串进行base64编码,接着通过bltBase64Decode模块函数将编码的字符串进行解码,同时将解码的结果转为字符串类型(通过将第三个参数设置为1) use builtin,openssl; def RSA_PUBLIC 1; def RSA_PRIVATE 0; def RSA_PKCS1_PADDING 0; def DUMP_HEX 2; ................................................................. key = read_rsa_key('rsa_public.key', RSA_PUBLIC); p_key = read_rsa_key('rsa_private.key', RSA_PRIVATE); print 'source string:' + (src_str = "hello world! I'm a programmer!") + br; enc_len = opensslPrivateEncrypt(src_str, -1, p_key, &enc); print 'encrypt: ' + bltDumpPtrData(enc, enc_len, DUMP_HEX) + br; print 'encrypt base64 encode: ' + (encode = bltBase64Encode(enc)) + br; decode_len = bltBase64Decode(encode, &decode); print 'decode_len: ' + decode_len + br; print 'decode: ' + bltDumpPtrData(decode, decode_len, DUMP_HEX) + br; dec_len = opensslPublicDecrypt(decode, decode_len, key, &dec, RSA_PKCS1_PADDING, TRUE); print 'decrypt string: ' + dec + br; 以上代码片段先将openssl加密后的二进制数据进行base64编码,接着通过bltBase64Decode将编码数据进行解码,从而获取到原始的加密二进制数据,最后通过openssl模块函数 将二进制数据解密为原始的字符串值 */ ZL_EXP_VOID module_builtin_base64_decode(ZL_EXP_VOID * VM_ARG, ZL_EXP_INT argcount) { ZENGL_EXPORT_MOD_FUN_ARG arg = {ZL_EXP_FAT_NONE,{0}}; const char * func_name = "bltBase64Decode"; if(argcount < 2) zenglApi_Exit(VM_ARG,"usage: %s(data, &result[, decode_to_str = 0]): integer", func_name); zenglApi_GetFunArg(VM_ARG,1,&arg); if(arg.type != ZL_EXP_FAT_STR) { zenglApi_Exit(VM_ARG,"the first argument [data] of %s must be string", func_name); } unsigned char * data = (unsigned char *)arg.val.str; int data_len = (int)strlen((char *)data); if(data_len > 0) { st_detect_arg_is_address_type(VM_ARG, 2, &arg, "second argument [&result]", func_name); int result_size = b64d_size(data_len); unsigned char * result = (unsigned char *)zenglApi_AllocMem(VM_ARG, (sizeof(char) * result_size) +1); memset(result, 0, ((sizeof(char) * result_size) +1)); int result_len = b64_decode(data, (unsigned int)data_len, result); int decode_to_str = 0; if(argcount > 2) { zenglApi_GetFunArg(VM_ARG,3,&arg); if(arg.type != ZL_EXP_FAT_INT) { zenglApi_Exit(VM_ARG,"the third argument [decode_to_str] of %s must be integer", func_name); } decode_to_str = (int)arg.val.integer; } if(decode_to_str) { st_set_arg_value(VM_ARG, 2, ZL_EXP_FAT_STR, (char *)result, 0); zenglApi_FreeMem(VM_ARG, result); } else { st_set_arg_value(VM_ARG, 2, ZL_EXP_FAT_INT, NULL, (ZL_EXP_LONG)result); MAIN_DATA * my_data = zenglApi_GetExtraData(VM_ARG, "my_data"); int ret_set_ptr = pointer_list_set_member(&(my_data->pointer_list), result, result_len, module_builtin_free_ptr_callback); if(ret_set_ptr != 0) { zenglApi_Exit(VM_ARG, "%s add pointer to pointer_list failed, pointer_list_set_member error code:%d", func_name, ret_set_ptr); } } zenglApi_SetRetVal(VM_ARG, ZL_EXP_FAT_INT, ZL_EXP_NULL, result_len, 0); } else { st_set_arg_value(VM_ARG, 2, ZL_EXP_FAT_INT, NULL, 0); zenglApi_SetRetVal(VM_ARG, ZL_EXP_FAT_INT, ZL_EXP_NULL, 0, 0); } }
当前版本增加了base64.h的头文件,以及base64.c的源码文件,之前介绍的bltBase64Encode和bltBase64Decode模块函数,都是通过base64.c文件中定义的b64_encode和b64_decode函数来完成具体的编解码操作的。
base64.h头文件的代码如下:
/* * base64.h * * Created on: May 21, 2020 * Author: zengl * * 以下代码来自github开源项目:https://github.com/joedf/base64.c */ /* base64.c - by Joe DF ([email protected]) Released under the MIT License Revision: 2015-06-12 01:26:51 Thank you for inspiration: http://www.codeproject.com/Tips/813146/Fast-base-functions-for-encode-decode */ #ifndef BASE64_H_ #define BASE64_H_ //Base64 char table function - used internally for decoding unsigned int b64_int(unsigned int ch); // in_size : the number bytes to be encoded. // Returns the recommended memory size to be allocated for the output buffer excluding the null byte unsigned int b64e_size(unsigned int in_size); // in_size : the number bytes to be decoded. // Returns the recommended memory size to be allocated for the output buffer unsigned int b64d_size(unsigned int in_size); // in : buffer of "raw" binary to be encoded. // in_len : number of bytes to be encoded. // out : pointer to buffer with enough memory, user is responsible for memory allocation, receives null-terminated string // returns size of output including null byte unsigned int b64_encode(const unsigned char* in, unsigned int in_len, unsigned char* out); // in : buffer of base64 string to be decoded. // in_len : number of bytes to be decoded. // out : pointer to buffer with enough memory, user is responsible for memory allocation, receives "raw" binary // returns size of output excluding null byte unsigned int b64_decode(const unsigned char* in, unsigned int in_len, unsigned char* out); #endif /* BASE64_H_ */
base64.c文件的代码如下:
/* * base64.c * * Created on: May 21, 2020 * Author: zengl * * 以下代码来自github开源项目:https://github.com/joedf/base64.c */ /* base64.c - by Joe DF ([email protected]) Released under the MIT License See "base64.h", for more information. Thank you for inspiration: http://www.codeproject.com/Tips/813146/Fast-base-functions-for-encode-decode */ #include "base64.h" //Base64 char table - used internally for encoding unsigned char b64_chr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //Base64 char table function - used internally for decoding unsigned int b64_int(unsigned int ch) { // ASCII to base64_int // 65-90 Upper Case >> 0-25 // 97-122 Lower Case >> 26-51 // 48-57 Numbers >> 52-61 // 43 Plus (+) >> 62 // 47 Slash (/) >> 63 // 61 Equal (=) >> 64~ if (ch==43) return 62; if (ch==47) return 63; if (ch==61) return 64; if ((ch>47) && (ch<58)) return ch + 4; if ((ch>64) && (ch<91)) return ch - 'A'; if ((ch>96) && (ch<123)) return (ch - 'a') + 26; return 0; } // in_size : the number bytes to be encoded. // Returns the recommended memory size to be allocated for the output buffer excluding the null byte unsigned int b64e_size(unsigned int in_size) { // size equals 4*floor((1/3)*(in_size+2)); int i, j = 0; for (i=0;i<in_size;i++) { if (i % 3 == 0) j += 1; } return (4*j); } // in_size : the number bytes to be decoded. // Returns the recommended memory size to be allocated for the output buffer unsigned int b64d_size(unsigned int in_size) { return ((3*in_size)/4); } // in : buffer of "raw" binary to be encoded. // in_len : number of bytes to be encoded. // out : pointer to buffer with enough memory, user is responsible for memory allocation, receives null-terminated string // returns size of output including null byte unsigned int b64_encode(const unsigned char* in, unsigned int in_len, unsigned char* out) { unsigned int i=0, j=0, k=0, s[3]; for (i=0;i<in_len;i++) { s[j++]=*(in+i); if (j==3) { out[k+0] = b64_chr[ (s[0]&255)>>2 ]; out[k+1] = b64_chr[ ((s[0]&0x03)<<4)+((s[1]&0xF0)>>4) ]; out[k+2] = b64_chr[ ((s[1]&0x0F)<<2)+((s[2]&0xC0)>>6) ]; out[k+3] = b64_chr[ s[2]&0x3F ]; j=0; k+=4; } } if (j) { if (j==1) s[1] = 0; out[k+0] = b64_chr[ (s[0]&255)>>2 ]; out[k+1] = b64_chr[ ((s[0]&0x03)<<4)+((s[1]&0xF0)>>4) ]; if (j==2) out[k+2] = b64_chr[ ((s[1]&0x0F)<<2) ]; else out[k+2] = '='; out[k+3] = '='; k+=4; } out[k] = '\0'; return k; } // in : buffer of base64 string to be decoded. // in_len : number of bytes to be decoded. // out : pointer to buffer with enough memory, user is responsible for memory allocation, receives "raw" binary // returns size of output excluding null byte unsigned int b64_decode(const unsigned char* in, unsigned int in_len, unsigned char* out) { unsigned int i=0, j=0, k=0, s[4]; for (i=0;i<in_len;i++) { s[j++]=b64_int(*(in+i)); if (j==4) { out[k+0] = ((s[0]&255)<<2)+((s[1]&0x30)>>4); if (s[2]!=64) { out[k+1] = ((s[1]&0x0F)<<4)+((s[2]&0x3C)>>2); if ((s[3]!=64)) { out[k+2] = ((s[2]&0x03)<<6)+(s[3]); k+=3; } else { k+=2; } } else { k+=1; } j=0; } } return k; }
当前版本在my_webroot目录中增加了v0_21_0的子目录,并在该目录中增加了test_base64.zl的测试脚本,用于测试对普通的字符串进行base64编解码的操作,test_base64.zl的代码如下:
use builtin; def TRUE 1; encode_str = bltBase64Encode("hello world"); print encode_str; decode_len = bltBase64Decode(encode_str, &decode, TRUE); print 'decode_len: ' + decode_len; print 'decode: ' + decode;
以上脚本的执行结果如下:
[root@localhost zenglServer]# ./zenglServer -r "/v0_21_0/test_base64.zl" aGVsbG8gd29ybGQ= decode_len: 11 decode: hello world [root@localhost zenglServer]#
当前版本在my_webroot/v0_21_0目录中,还增加了test_base64_openssl.zl的测试脚本,用于测试对加密后的二进制数据进行base64编解码,该测试脚本的代码如下:
use builtin,openssl; def RSA_PUBLIC 1; def RSA_PRIVATE 0; def RSA_PKCS1_PADDING 0; def TRUE 1; def FALSE 0; def NULL 0; def DUMP_HEX 2; if(bltIsRunInCmd()) bltSetImmediatePrint(TRUE); print 'now in cmd'; is_cmd = TRUE; br = '\n'; else is_cmd = FALSE; br = '<br/><br/>'; print 'now in website' + br; endif fun exit(msg) global is_cmd,br; print msg + br; bltExit(); endfun fun read_rsa_key(file, is_public, password = '') global is_cmd,br; ret = bltReadFile(file, &key_content, &file_size); if(ret == 0) // print file + ' file size: ' + file_size + br; if(password) key = opensslReadKey(key_content, is_public, password); else key = opensslReadKey(key_content, is_public); endif if(key == NULL) exit('read key "'+ file +'" failed: ' + opensslGetError()); endif // print 'key:' + key + br; return key; else exit('read '+file+' failed, maybe the file does not exists, or open failed.'); endif endfun key = read_rsa_key('rsa_public.key', RSA_PUBLIC); p_key = read_rsa_key('rsa_private.key', RSA_PRIVATE); print 'source string:' + (src_str = "hello world! I'm a programmer!") + br; enc_len = opensslPrivateEncrypt(src_str, -1, p_key, &enc); print 'encrypt: ' + bltDumpPtrData(enc, enc_len, DUMP_HEX) + br; print 'encrypt base64 encode: ' + (encode = bltBase64Encode(enc)) + br; decode_len = bltBase64Decode(encode, &decode); print 'decode_len: ' + decode_len + br; print 'decode: ' + bltDumpPtrData(decode, decode_len, DUMP_HEX) + br; dec_len = opensslPublicDecrypt(decode, decode_len, key, &dec, RSA_PKCS1_PADDING, TRUE); print 'decrypt string: ' + dec + br;
以上测试脚本的执行结果如下:
[root@localhost zenglServer]# ./zenglServer -r "/v0_21_0/test_base64_openssl.zl" now in cmd source string:hello world! I'm a programmer! encrypt: 11 47 B0 0B BC E8 71 3D B2 95 6D 0E A7 C4 17 CB BB CD 86 20 E4 B2 D3 3B D2 DE C8 57 BA AE C8 1D B2 2D 42 BB 5C 33 08 6C EE DA 4D F4 4F 0D 94 0D 4A 12 46 B5 B1 AD 08 C4 A6 C6 5F DF 37 10 BE 5B 31 E7 CA 0D BE C7 31 6C 9C 4A 09 12 69 45 46 A4 FE C0 8E DA FC CC F4 FC 4B A6 95 E1 01 99 2A 73 22 55 44 ED B0 FA 7F D1 E0 EC F3 7E 54 43 E5 08 F7 51 73 65 E8 2B 5C FC C2 04 D3 C4 94 FB 78 35 8E 31 4B A9 4E A2 77 A6 78 34 12 71 DC 2E 59 69 D9 04 31 18 58 DE 2F 80 92 6C DA DD 18 4E 2B 78 93 74 D3 21 A4 73 E1 53 DC 82 69 8F 12 1C 1E 73 3E 09 28 59 0D 68 03 A0 2F 64 C3 66 F1 2B FA AF 8A C1 B6 57 00 FD 46 E2 0F AC 85 1C 8C 32 52 F7 73 CB B1 60 B9 6C 66 97 E7 F7 4B 8E ED 2F A4 23 2E C5 53 40 56 5A D1 C2 07 C4 74 84 CA 53 0D 33 C7 5D 15 A7 26 EB 43 2A D3 34 85 B6 6C 57 02 B2 encrypt base64 encode: EUewC7zocT2ylW0Op8QXy7vNhiDkstM70t7IV7quyB2yLUK7XDMIbO7aTfRPDZQNShJGtbGtCMSmxl/fNxC+WzHnyg2+xzFsnEoJEmlFRqT+wI7a/Mz0/EumleEBmSpzIlVE7bD6f9Hg7PN+VEPlCPdRc2XoK1z8wgTTxJT7eDWOMUupTqJ3png0EnHcLllp2QQxGFjeL4CSbNrdGE4reJN00yGkc+FT3IJpjxIcHnM+CShZDWgDoC9kw2bxK/qvisG2VwD9RuIPrIUcjDJS93PLsWC5bGaX5/dLju0vpCMuxVNAVlrRwgfEdITKUw0zx10VpybrQyrTNIW2bFcCsg== decode_len: 256 decode: 11 47 B0 0B BC E8 71 3D B2 95 6D 0E A7 C4 17 CB BB CD 86 20 E4 B2 D3 3B D2 DE C8 57 BA AE C8 1D B2 2D 42 BB 5C 33 08 6C EE DA 4D F4 4F 0D 94 0D 4A 12 46 B5 B1 AD 08 C4 A6 C6 5F DF 37 10 BE 5B 31 E7 CA 0D BE C7 31 6C 9C 4A 09 12 69 45 46 A4 FE C0 8E DA FC CC F4 FC 4B A6 95 E1 01 99 2A 73 22 55 44 ED B0 FA 7F D1 E0 EC F3 7E 54 43 E5 08 F7 51 73 65 E8 2B 5C FC C2 04 D3 C4 94 FB 78 35 8E 31 4B A9 4E A2 77 A6 78 34 12 71 DC 2E 59 69 D9 04 31 18 58 DE 2F 80 92 6C DA DD 18 4E 2B 78 93 74 D3 21 A4 73 E1 53 DC 82 69 8F 12 1C 1E 73 3E 09 28 59 0D 68 03 A0 2F 64 C3 66 F1 2B FA AF 8A C1 B6 57 00 FD 46 E2 0F AC 85 1C 8C 32 52 F7 73 CB B1 60 B9 6C 66 97 E7 F7 4B 8E ED 2F A4 23 2E C5 53 40 56 5A D1 C2 07 C4 74 84 CA 53 0D 33 C7 5D 15 A7 26 EB 43 2A D3 34 85 B6 6C 57 02 B2 decrypt string: hello world! I'm a programmer! [root@localhost zenglServer]#
恋爱是容易的,成家是困难的
相爱是容易的,相处是困难的
决定是容易的,可是等待是困难的
—— 《爱情麻辣烫》