前言
lua语言性能对比
1、DHexchange密钥交换算法
Diffie-Hellman算法是Whitefield Diffie和Martin Hellman在1976年公布的一种秘钥交换算法,是最早的密钥交换算法之一,它是一种建立秘钥的方法,而不是加密方法,所以秘钥必须和其他一种加密算法结合使用。这种秘钥交换技术的目的在于使两个用户安全的交换一个秘钥以便后面的报文加密,被应用于安全领域,比如 Https 协议的 TSL(Transport Layer Security) 和 IPsec 协议的 IKE(Internet Key Exchange) 均以 DH 算法作为密钥交换算法。
它的数学基础就是离散对数这个数学难题。用它进行密钥交换的过程简述如下:
- 选取两个大的素数n和g并公开,其中n是一个素数,g是n的一个模n本原单位根(primitive root module n),所谓本原单位根就是指在模n乘法运算下,g的1次方,2次方……(n-1)次方这n-1个数互不相同,并且取遍1到n-1;
- 对于甲方(其中的一个通信者),随机产生一个整数a,a对外保密,计算Ka = g^a mod n,将Ka发送给乙方;
- 对于乙方(另一个通信者),随机产生一个整数b,b对外保密,计算Kb = g^b mod n,将Kb发送给甲方;
- 在甲方方面,收到乙方送来的Kb后,计算出密钥为:key = Kb^a mod n = g^(b*a) mod n mod n;
- 对于乙方,收到甲方送来的Ka后,计算出密钥为:key = Ka ^ b mod n = g^(a*b) mod n mod n。
- 攻击者知道n和g,并且截获了Ka和Kb,但是当它们都是非常大的数的时候,依靠这四个数来计算a和b非常困难,这就是离散对数数学难题。
1.1、lua代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package.cpath = "luaclib/?.so" local crypt = require "client.crypt" local clientkey = "11111111" --8byte random print("clientkey:" , clientkey) local ckey = crypt.dhexchange(clientkey) print("ckey:\t" , crypt.hexencode(ckey) local serverkey = "22222222" print("serverkey:" , serverkey) local skey = crypt.dhexchange(serverkey) print("skey:\t" , crypt.hexencode(skey)) local csecret = crypt.dhsecret(skey, clientkey) print("use skey clientkey dhsecret:", crypt.hexencode(csecret)) --交换成功 local ssecret = crypt.dhsecret(ckey, serverkey) print("use ckey serverkey dhsecret:", crypt.hexencode(ssecret)) --交换成功 local ssecret = crypt.dhsecret(ckey, skey) --交换失败 print("use ckey skey dhsecret:\t", crypt.hexencode(ssecret)) |
上面的代码运行输出:
1 2 3 4 5 6 7 |
clientkey: 11111111 ckey: D5 8A 46 9C FD ED 70 5E serverkey: 22222222 skey: B3 60 21 D9 C4 C5 1B 0C use skey clientkey dhsecret: 95 69 12 B6 88 B3 3B 42 #交换成功 use ckey serverkey dhsecret: 95 69 12 B6 88 B3 3B 42 #交换成功 use ckey skey dhsecret: C7 19 E5 5F 0A 34 DC E8 #交换不成功 |
2、将字符串转为ASCII 码数组
1 2 3 4 5 6 7 |
local ascii_arr = {} local target_str = "test" local str_len = string.len(target_str) for i=1, str_len do --获取字符ascii码值 table.insert(ascii_arr, i, target_str:byte(i)) end |
3、将10进制数转换为16进制数
1 2 3 4 5 6 7 8 9 10 11 |
--0x: --前面的0x只是个普通的字符串,可有可无, --因为我们一般在十六进制数前面加上0x来表明这是一个十六进制数, --所以这里才加了个0x,没有其他特殊意义 --%后面的0: --表示不足位数时的填充数,通常用0填充。 --%后面第二个数字2: --表示格式化成多少位 --x: --接受一个数字并将其转化为小写的十六进制格式,如果是大写X则表示转换为大写的十六进制格式 local hex_val = string.format("0x%02x", val) |
4、16进制转换为10进制
1 |
local n = tonumber(hex_char, 16) |
5、按位取反
1 2 3 |
-- ‘~’ 为异或操作符 -- 注意:hex_val必须为0x开头,不然会被判断为10进制数 string.format("%x", hex_val ~ 0xFF) |
6、10进制和字符相互转换
1 2 3 4 5 6 7 |
local test_str = "test" --字符串里面 i 位置的字符的ascii码值 test_str:byte(i) local n = 97 --n 为 ascii码的整形值,转换为对应的字符‘a' string.char(n) |
7、chunk拼接
1 2 3 4 5 |
local image_datas = {} --for start table.insert(image_datas, media_data) --for end local chunk_data = table.concat(image_datas) |
8、版本比较
8.1、lua代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
-- 版本比较 -- 1: version1大于version2, 0:version1等于version2, -1:version1小于version2 local function compare_versions(version1, version2) if version1 == nil or version1 == '' or version2 == nil or version2 == '' then if version1 ~= nil and version1 ~= '' then return 1 elseif version2 ~= nil and version2 ~= '' then return -1 else return 0 end end local version_arr1 = split_string(version1, '%.') local version_arr2 = split_string(version2, '%.') local min_len = math.min(#version_arr1, #version_arr2) local diff = 0; --lua index从1开始 local idx = 1 while (idx <= min_len) do local str1 = version_arr1[idx] local str2 = version_arr2[idx] diff = string.len(str1) - string.len(str2) if diff == 0 then if str1 == str2 then diff = 0 elseif str1 > str2 then diff = 1 else diff = -1 end end if diff ~= 0 then break else idx = idx + 1 end end --如果已经分出大小,则直接返回,如果未分出大小,则再比较位数,有子版本的为大; if diff ~= 0 then if diff > 0 then return 1 else return -1 end else local len = #version_arr1 - #version_arr2 if len > 0 then return 1 elseif len == 0 then return 0 else return -1 end end end |
8.2、测试用例
lu.assertEquals为内部实现可以忽略
1 2 3 4 5 6 7 8 9 10 11 12 |
function TestVersionCheck:testCompareVersions() lu.assertEquals(-1, version_check.compare_versions("1.0.0", "1.2.3")) lu.assertEquals(-1, version_check.compare_versions("1.0.0", "1.2")) lu.assertEquals(0, version_check.compare_versions("1.0.0", "1.0.0")) lu.assertEquals(-1, version_check.compare_versions("1.0.0", "1.0.0.1")) lu.assertEquals(1, version_check.compare_versions("1.0.0", nil)) lu.assertEquals(1, version_check.compare_versions("1.0.0", "")) lu.assertEquals(1, version_check.compare_versions("1.123.0", "1")) lu.assertEquals(1, version_check.compare_versions("1.123.0", "1.1")) lu.assertEquals(1, version_check.compare_versions("1.10.0", "1.9")) lu.assertEquals(1, version_check.compare_versions("1.10.0", "1.9.0")) end |