Files
2HUCardTDGame/game/scripts/vscripts/util.lua
2021-11-10 08:48:00 -05:00

1200 lines
36 KiB
Lua
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- 打印表格
function PrintTable(t, indent, done)
--print ( string.format ('PrintTable type %s', type(keys)) )
if type(t) ~= "table" then return end
done = done or {}
done[t] = true
indent = indent or 0
local l = {}
for k, v in pairs(t) do
table.insert(l, k)
end
table.sort(l)
for k, v in ipairs(l) do
-- Ignore FDesc
if v ~= 'FDesc' then
local value = t[v]
if type(value) == "table" and not done[value] then
done [value] = true
print(string.rep ("\t", indent)..tostring(v)..":")
PrintTable (value, indent + 2, done)
elseif type(value) == "userdata" and not done[value] then
done [value] = true
print(string.rep ("\t", indent)..tostring(v)..": "..tostring(value))
PrintTable ((getmetatable(value) and getmetatable(value).__index) or getmetatable(value), indent + 2, done)
else
if t.FDesc and t.FDesc[v] then
print(string.rep ("\t", indent)..tostring(t.FDesc[v]))
else
print(string.rep ("\t", indent)..tostring(v)..": "..tostring(value))
end
end
end
end
end
-- ***** string 功能扩展开始 ******
-- RC4
-- http://en.wikipedia.org/wiki/RC4
function RC4encrypt(text,key)
function KSA(key)
local key_len = string.len(key)
local S = {}
local key_byte = {}
for i = 0, 255 do
S[i] = i
end
for i = 1, key_len do
key_byte[i-1] = string.byte(key, i, i)
end
local j = 0
for i = 0, 255 do
j = (j + S[i] + key_byte[i % key_len]) % 256
S[i], S[j] = S[j], S[i]
end
return S
end
function PRGA(S, text_len)
local i = 0
local j = 0
local K = {}
for n = 1, text_len do
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
K[n] = S[(S[i] + S[j]) % 256]
end
return K
end
function RC4(key, text)
local text_len = string.len(text)
local S = KSA(key)
local K = PRGA(S, text_len)
return output(K, text)
end
function output(S, text)
local len = string.len(text)
local c = nil
local res = {}
for i = 1, len do
c = string.byte(text, i, i)
res[i] = string.char(bxor(S[i], c))
end
return table.concat(res)
end
-------------------------------
-------------bit wise-----------
-------------------------------
local bit_op = {}
function bit_op.cond_and(r_a, r_b)
return (r_a + r_b == 2) and 1 or 0
end
function bit_op.cond_xor(r_a, r_b)
return (r_a + r_b == 1) and 1 or 0
end
function bit_op.cond_or(r_a, r_b)
return (r_a + r_b > 0) and 1 or 0
end
function bit_op.base(op_cond, a, b)
-- bit operation
if a < b then
a, b = b, a
end
local res = 0
local shift = 1
while a ~= 0 do
r_a = a % 2
r_b = b % 2
res = shift * bit_op[op_cond](r_a, r_b) + res
shift = shift * 2
a = math.modf(a / 2)
b = math.modf(b / 2)
end
return res
end
function bxor(a, b)
return bit_op.base('cond_xor', a, b)
end
function band(a, b)
return bit_op.base('cond_and', a, b)
end
function bor(a, b)
return bit_op.base('cond_or', a, b)
end
local textLen = string.len(text)
local schedule = KSA(key)
local k = PRGA(schedule, textLen)
return output(k, text)
end
--将字符串按格式转为16进制串
function string.tohex(str)
--判断输入类型
if (type(str)~="string") then
return nil,"string2hex invalid input type"
end
--拼接字符串
local index=1
local ret=""
for index=1,str:len() do
ret=ret..string.format("%02X",str:sub(index):byte())
end
return ret
end
--将16进制串转换为字符串
function string.fromhex(hex)
--判断输入类型
if (type(hex)~="string") then
return nil,"hex2string invalid input type"
end
--滤掉分隔符
hex=hex:gsub("[%s%p]",""):upper()
--检查内容是否合法
if(hex:find("[^0-9A-Fa-f]")~=nil) then
return nil,"hex2string invalid input content"
end
--检查字符串长度
if(hex:len()%2~=0) then
return nil,"hex2string invalid input lenth"
end
--拼接字符串
local index=1
local ret=""
for index=1,hex:len(),2 do
ret=ret..string.char(tonumber(hex:sub(index,index+1),16))
end
return ret
end
-- 字符串编码
function string.encode(text, key)
if text == nil or string.len(text) == 0 then return text end
return string.tohex(RC4encrypt(text, key))
end
-- 字符串解码
function string.decode(text, key)
if text == nil or string.len(text) == 0 then return text end
local s,e = string.fromhex(text)
if s == nil then
return s,e
else
return RC4encrypt(s, key)
end
end
-- 字符串分割,返回分割后子串数组
function string.split(input, delimiter)
input = tostring(input)
delimiter = tostring(delimiter)
if (delimiter=='') then return false end
local pos,arr = 0, {}
for st,sp in function() return string.find(input, delimiter, pos, true) end do
table.insert(arr, string.sub(input, pos, st - 1))
pos = sp + 1
end
table.insert(arr, string.sub(input, pos))
return arr
end
-- 字符串输出到文件
function string.tofile(str, path)
local out = io.open(path,"w")
if out then
out:write(str)
out:close()
end
end
-- 超长字符串格式化的方式输出到文件,使用方法 table.concat(t)
function string.tablefile(str, path)
local out = io.open(path,"w")
if out then
out:write('{\n')
local len = string.len(str)
local step = 255
local n = math.floor(len/step)
for i=0,n-1 do
out:write(' "'..string.sub(str, i*step+1, (i+1)*step)..'",\n')
end
out:write(' "'..string.sub(str, n*step+1, (n+1)*step)..'"\n}')
out:close()
end
end
-- 从kv文件中载入字符串对应 string.savekvfile 的输出
function string.loadkvfile(path)
local t = LoadKeyValues(path)
if t == nil or t["1"] == nil then return nil end
local ret = t["1"]
local i = 2
while(t[tostring(i)] ~= nil)
do
ret = ret..t[tostring(i)]
i = i + 1
end
t = {}
return ret
end
--[[
以字符串内容写入文件,成功返回 true失败返回 false
"mode 写入模式" 参数决定 io.writefile() 如何写入内容,可用的值如下:
- "w+" : 覆盖文件已有内容,如果文件不存在则创建新文件
- "a+" : 追加内容到文件尾部,如果文件不存在则创建文件
此外,还可以在 "写入模式" 参数最后追加字符 "b" ,表示以二进制方式写入数据,这样可以避免内容写入不完整。
- 默认值为 "w+b"
path 文件完全路径
content 要写入的内容
--]]
function string.writefile(content, path, mode)
mode = mode or "w+b"
local file = io.open(path, mode)
if file then
if file:write(content) == nil then return false end
io.close(file)
return true
else
return false
end
end
-- ***** string 功能扩展结束 ******
-- ***** table 功能扩展开始 ******
-- table和string的互转
function table.tostring(t)
function ToStringEx(value)
if type(value)=='table' then
return table.tostring(value)
elseif type(value)=='string' then
return "\'"..value.."\'"
else
return tostring(value)
end
end
if t == nil then return "" end
local retstr= "{"
local i = 1
for key,value in pairs(t) do
local signal = ","
if i==1 then
signal = ""
end
if key == i then
retstr = retstr..signal..ToStringEx(value)
else
if type(key)=='number' or type(key) == 'string' then
retstr = retstr..signal..'['..ToStringEx(key).."]="..ToStringEx(value)
else
if type(key)=='userdata' then
retstr = retstr..signal.."*s"..table.tostring(getmetatable(key)).."*e".."="..ToStringEx(value)
else
retstr = retstr..signal..key.."="..ToStringEx(value)
end
end
end
i = i+1
end
retstr = retstr.."}"
return retstr
end
-- table和string的互转
function table.fromstring(str)
if str == nil or type(str) ~= "string" then
return
end
print(str)
-- loadstring在lua5.2中已经被弃用了
--return loadstring("return " .. str)()
return load("return " .. str)()
end
-- table按键名排序遍历默认为升序
-- t为table, method为排序方式asc或descfunc为遍历回调
-- lua中table是按照hash排列的ipairs可以顺序遍历但是不一定全部结果都能遍历出来pairs能够全部遍历但是遍历出来的结果是随机的故需使用此方法
function table.sorteach(t, func, method)
local tableTemp = {}
for i in pairs(t) do
if i ~= nil then
table.insert(tableTemp, i)
end
end
if method == "desc" or method == "DESC" then
-- 降序
table.sort(tableTemp, function(a,b) return (a > b) end)
else
-- 升序
table.sort(tableTemp, function(a,b) return (a < b) end)
end
-- 遍历
for _, key in pairs(tableTemp) do
if type(func) == "function" then func(key, t[key]) end
end
tableTemp = {}
end
-- 深度复制表
function table.deepcopy(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for index, value in pairs(object) do
new_table[_copy(index)] = _copy(value)
end
return setmetatable(new_table, getmetatable(object))
end
return _copy(object)
end
-- 判断键是否在table中
function table.haskey(t, key)
for k,v in pairs(t) do
if k == key then return true end
end
return false
end
-- 判断值是否在table中
function table.hasvalue(t, value)
for k,v in pairs(t) do
if v == value then return true end
end
return false
end
-- 从文件中载入数据,来源对应加密数据
function table.loadkv(path)
--return table.fromstring(string.decode(string.loadkvfile(path), ""))
return table.fromstring(string.decode(string.loadkvfile(path), SERVER_KEY))
end
-- Should read a lua table string from a file and return the table again, we'll see when it's tested
function table.fromfile(path)
local file = io.open(path, "r")
return table.fromstring(file:read("a"))
end
-- 获取表中值元素的长度不计nil
function table.count(t)
if type(t) ~= "table" then
return 0
end
local len = 0
for k,v in pairs(t) do
if v ~= nil then
len = len + 1
end
end
return len
end
-- 获取表按升序排列的第index元素对应的key排除值为nil的元素异常返回 nil
function table.getkey(t, index)
if type(t) ~= "table" or index == nil then
return nil
end
local tableTemp = {}
for k in pairs(t) do
if k ~= nil then
table.insert(tableTemp, k)
end
end
-- 降序
-- table.sort(tableTemp, function(a,b) return (a > b) end)
-- 升序
table.sort(tableTemp, function(a,b) return (a < b) end)
local key = nil
local count = 0
if index >= 1 or index <= #tableTemp then
key = tableTemp[index]
end
tableTemp = {}
return key
end
-- 按 key 顺序循环f为可选参数用于指定排序顺序
function pairsByKeys(t,f)
local a = {}
for n in pairs(t) do a[#a + 1] = n end
table.sort(a, f)
local i = 0
return function()
i = i + 1
return a[i], t[a[i]]
end
end
--~ 使用上述迭代器:
-- for k,v in pairsByKeys(inputTable) do
-- print(k, v)
-- end
-- 按 key 顺序获取指定key的序号
function table.keyindex(t, key)
local index = 0
for k,v in pairsByKeys(t) do
index = index + 1
if k == key then
return index
end
end
return nil
end
-- ***** table 功能扩展结束 ******
-- ***** MD5 功能开始 ******
-- 使用 md5.sumhexa(message)
md5 = {
_VERSION = "md5.lua 1.1.0",
_DESCRIPTION = "MD5 computation in Lua (5.1-3, LuaJIT)",
_URL = "https://github.com/kikito/md5.lua",
_LICENSE = [[
MIT LICENSE
Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
}
-- bit lib implementions
local char, byte, format, rep, sub =
string.char, string.byte, string.format, string.rep, string.sub
local bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift
local ok, bit = pcall(require, 'bit')
if ok then
bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift = bit.bor, bit.band, bit.bnot, bit.bxor, bit.rshift, bit.lshift
else
ok, bit = pcall(require, 'bit32')
if ok then
bit_not = bit.bnot
local tobit = function(n)
return n <= 0x7fffffff and n or -(bit_not(n) + 1)
end
local normalize = function(f)
return function(a,b) return tobit(f(tobit(a), tobit(b))) end
end
bit_or, bit_and, bit_xor = normalize(bit.bor), normalize(bit.band), normalize(bit.bxor)
bit_rshift, bit_lshift = normalize(bit.rshift), normalize(bit.lshift)
else
local function tbl2number(tbl)
local result = 0
local power = 1
for i = 1, #tbl do
result = result + tbl[i] * power
power = power * 2
end
return result
end
local function expand(t1, t2)
local big, small = t1, t2
if(#big < #small) then
big, small = small, big
end
-- expand small
for i = #small + 1, #big do
small[i] = 0
end
end
local to_bits -- needs to be declared before bit_not
bit_not = function(n)
local tbl = to_bits(n)
local size = math.max(#tbl, 32)
for i = 1, size do
if(tbl[i] == 1) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
-- defined as local above
to_bits = function (n)
if(n < 0) then
-- negative
return to_bits(bit_not(math.abs(n)) + 1)
end
-- to bits table
local tbl = {}
local cnt = 1
local last
while n > 0 do
last = n % 2
tbl[cnt] = last
n = (n-last)/2
cnt = cnt + 1
end
return tbl
end
bit_or = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
for i = 1, #tbl_m do
if(tbl_m[i]== 0 and tbl_n[i] == 0) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
bit_and = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
for i = 1, #tbl_m do
if(tbl_m[i]== 0 or tbl_n[i] == 0) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
bit_xor = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
for i = 1, #tbl_m do
if(tbl_m[i] ~= tbl_n[i]) then
tbl[i] = 1
else
tbl[i] = 0
end
end
return tbl2number(tbl)
end
bit_rshift = function(n, bits)
local high_bit = 0
if(n < 0) then
-- negative
n = bit_not(math.abs(n)) + 1
high_bit = 0x80000000
end
local floor = math.floor
for i=1, bits do
n = n/2
n = bit_or(floor(n), high_bit)
end
return floor(n)
end
bit_lshift = function(n, bits)
if(n < 0) then
-- negative
n = bit_not(math.abs(n)) + 1
end
for i=1, bits do
n = n*2
end
return bit_and(n, 0xFFFFFFFF)
end
end
end
-- convert little-endian 32-bit int to a 4-char string
local function lei2str(i)
local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end
return f(0)..f(8)..f(16)..f(24)
end
-- convert raw string to big-endian int
local function str2bei(s)
local v=0
for i=1, #s do
v = v * 256 + byte(s, i)
end
return v
end
-- convert raw string to little-endian int
local function str2lei(s)
local v=0
for i = #s,1,-1 do
v = v*256 + byte(s, i)
end
return v
end
-- cut up a string in little-endian ints of given size
local function cut_le_str(s,...)
local o, r = 1, {}
local args = {...}
for i=1, #args do
table.insert(r, str2lei(sub(s, o, o + args[i] - 1)))
o = o + args[i]
end
return r
end
local swap = function (w) return str2bei(lei2str(w)) end
-- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh)
-- 10/02/2001 jcw@equi4.com
local CONSTS = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
}
local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end
local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end
local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end
local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end
local z=function (ff,a,b,c,d,x,s,ac)
a=bit_and(a+ff(b,c,d)+x+ac,0xFFFFFFFF)
-- be *very* careful that left shift does not cause rounding!
return bit_or(bit_lshift(bit_and(a,bit_rshift(0xFFFFFFFF,s)),s),bit_rshift(a,32-s))+b
end
local function transform(A,B,C,D,X)
local a,b,c,d=A,B,C,D
local t=CONSTS
a=z(f,a,b,c,d,X[ 0], 7,t[ 1])
d=z(f,d,a,b,c,X[ 1],12,t[ 2])
c=z(f,c,d,a,b,X[ 2],17,t[ 3])
b=z(f,b,c,d,a,X[ 3],22,t[ 4])
a=z(f,a,b,c,d,X[ 4], 7,t[ 5])
d=z(f,d,a,b,c,X[ 5],12,t[ 6])
c=z(f,c,d,a,b,X[ 6],17,t[ 7])
b=z(f,b,c,d,a,X[ 7],22,t[ 8])
a=z(f,a,b,c,d,X[ 8], 7,t[ 9])
d=z(f,d,a,b,c,X[ 9],12,t[10])
c=z(f,c,d,a,b,X[10],17,t[11])
b=z(f,b,c,d,a,X[11],22,t[12])
a=z(f,a,b,c,d,X[12], 7,t[13])
d=z(f,d,a,b,c,X[13],12,t[14])
c=z(f,c,d,a,b,X[14],17,t[15])
b=z(f,b,c,d,a,X[15],22,t[16])
a=z(g,a,b,c,d,X[ 1], 5,t[17])
d=z(g,d,a,b,c,X[ 6], 9,t[18])
c=z(g,c,d,a,b,X[11],14,t[19])
b=z(g,b,c,d,a,X[ 0],20,t[20])
a=z(g,a,b,c,d,X[ 5], 5,t[21])
d=z(g,d,a,b,c,X[10], 9,t[22])
c=z(g,c,d,a,b,X[15],14,t[23])
b=z(g,b,c,d,a,X[ 4],20,t[24])
a=z(g,a,b,c,d,X[ 9], 5,t[25])
d=z(g,d,a,b,c,X[14], 9,t[26])
c=z(g,c,d,a,b,X[ 3],14,t[27])
b=z(g,b,c,d,a,X[ 8],20,t[28])
a=z(g,a,b,c,d,X[13], 5,t[29])
d=z(g,d,a,b,c,X[ 2], 9,t[30])
c=z(g,c,d,a,b,X[ 7],14,t[31])
b=z(g,b,c,d,a,X[12],20,t[32])
a=z(h,a,b,c,d,X[ 5], 4,t[33])
d=z(h,d,a,b,c,X[ 8],11,t[34])
c=z(h,c,d,a,b,X[11],16,t[35])
b=z(h,b,c,d,a,X[14],23,t[36])
a=z(h,a,b,c,d,X[ 1], 4,t[37])
d=z(h,d,a,b,c,X[ 4],11,t[38])
c=z(h,c,d,a,b,X[ 7],16,t[39])
b=z(h,b,c,d,a,X[10],23,t[40])
a=z(h,a,b,c,d,X[13], 4,t[41])
d=z(h,d,a,b,c,X[ 0],11,t[42])
c=z(h,c,d,a,b,X[ 3],16,t[43])
b=z(h,b,c,d,a,X[ 6],23,t[44])
a=z(h,a,b,c,d,X[ 9], 4,t[45])
d=z(h,d,a,b,c,X[12],11,t[46])
c=z(h,c,d,a,b,X[15],16,t[47])
b=z(h,b,c,d,a,X[ 2],23,t[48])
a=z(i,a,b,c,d,X[ 0], 6,t[49])
d=z(i,d,a,b,c,X[ 7],10,t[50])
c=z(i,c,d,a,b,X[14],15,t[51])
b=z(i,b,c,d,a,X[ 5],21,t[52])
a=z(i,a,b,c,d,X[12], 6,t[53])
d=z(i,d,a,b,c,X[ 3],10,t[54])
c=z(i,c,d,a,b,X[10],15,t[55])
b=z(i,b,c,d,a,X[ 1],21,t[56])
a=z(i,a,b,c,d,X[ 8], 6,t[57])
d=z(i,d,a,b,c,X[15],10,t[58])
c=z(i,c,d,a,b,X[ 6],15,t[59])
b=z(i,b,c,d,a,X[13],21,t[60])
a=z(i,a,b,c,d,X[ 4], 6,t[61])
d=z(i,d,a,b,c,X[11],10,t[62])
c=z(i,c,d,a,b,X[ 2],15,t[63])
b=z(i,b,c,d,a,X[ 9],21,t[64])
return bit_and(A+a,0xFFFFFFFF),bit_and(B+b,0xFFFFFFFF),
bit_and(C+c,0xFFFFFFFF),bit_and(D+d,0xFFFFFFFF)
end
----------------------------------------------------------------
local function md5_update(self, s)
self.pos = self.pos + #s
s = self.buf .. s
for ii = 1, #s - 63, 64 do
local X = cut_le_str(sub(s,ii,ii+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4)
assert(#X == 16)
X[0] = table.remove(X,1) -- zero based!
self.a,self.b,self.c,self.d = transform(self.a,self.b,self.c,self.d,X)
end
self.buf = sub(s, math.floor(#s/64)*64 + 1, #s)
return self
end
local function md5_finish(self)
local msgLen = self.pos
local padLen = 56 - msgLen % 64
if msgLen % 64 > 56 then padLen = padLen + 64 end
if padLen == 0 then padLen = 64 end
local s = char(128) .. rep(char(0),padLen-1) .. lei2str(bit_and(8*msgLen, 0xFFFFFFFF)) .. lei2str(math.floor(msgLen/0x20000000))
md5_update(self, s)
assert(self.pos % 64 == 0)
return lei2str(self.a) .. lei2str(self.b) .. lei2str(self.c) .. lei2str(self.d)
end
----------------------------------------------------------------
function md5.new()
return { a = CONSTS[65], b = CONSTS[66], c = CONSTS[67], d = CONSTS[68],
pos = 0,
buf = '',
update = md5_update,
finish = md5_finish }
end
function md5.tohex(s)
return format("%08x%08x%08x%08x", str2bei(sub(s, 1, 4)), str2bei(sub(s, 5, 8)), str2bei(sub(s, 9, 12)), str2bei(sub(s, 13, 16)))
end
function md5.sum(s)
return md5.new():update(s):finish()
end
function md5.sumhexa(s)
return md5.tohex(md5.sum(s))
end
-- ***** MD5 功能结束 ******
-- ***** datetime 功能开始 ******
datetime = {}
--[[
|=========================================================================
| 判断是否为闰年
|=========================================================================
| @param {int} year
| @return boolean
]]
function datetime.isLeapYear(year)
return (year%4 == 0 and year%100 ~= 0) or (year%400 == 0)
end
--[[
|=========================================================================
| 获取UNIX时间戳
|=========================================================================
| 以UTC时间为标准
|
| @param {string} datetime 只支持格式'2016-10-13 01:01:01'
| @return int
]]
function datetime.toUnixTime(datetimeString)
local datetimeTable = string.split(datetimeString,' ')
local datepart = string.split(datetimeTable[1],'-')
local timepart = string.split(datetimeTable[2],':')
local sec = tonumber(timepart[3]) + tonumber(timepart[2])*60 + tonumber(timepart[1])*60*60 + (tonumber(datepart[3]) - 1)*86400
local year = tonumber(datepart[1])
local m = tonumber(datepart[2]) - 1
for i=1,m do
if i==1 or i==3 or i==5 or i==7 or i==8 or i==10 or i==12 then
sec = sec + 31 * 86400
elseif i==4 or i==6 or i==9 or i==11 then
sec = sec + 30 * 86400
else
if datetime.isLeapYear(year) then
sec = sec + 29 * 86400
else
sec = sec + 28 * 86400
end
end
end
local day = 0
for i=1970,year-1 do
if datetime.isLeapYear(i) then
day = day + 366
else
day = day + 365
end
end
sec = sec + day * 86400
return sec
end
--[[
|=========================================================================
| 把UNIX时间戳转换成日期格式
|=========================================================================
| 以UTC时间为标准输出格式'2016-10-13 01:01:01'
|
| @param {int} unixtime
| @param {boolean} [returnTable] 可选如果为true返回table
| @return string|table
]]
function datetime.toDatetime(unixtime, returnTable )
local day = math.floor(unixtime/86400)
local year = 1970
while day >= 365 do
if datetime.isLeapYear(year) then
day = day - 366
unixtime = unixtime - 366*86400
else
day = day - 365
unixtime = unixtime - 365*86400
end
year = year + 1
end
_day = 0
local month = 0
for i=1,12 do
local d
if i==1 or i==3 or i==5 or i==7 or i==8 or i==10 or i==12 then
d = 31
elseif i==4 or i==6 or i==9 or i==11 then
d = 30
else
if datetime.isLeapYear(year) then
d = 29
else
d = 28
end
end
_day = _day + d
if day < _day then
month = i
unixtime = unixtime - (_day-d)*86400
break
end
end
day = math.floor(unixtime/86400)
unixtime = unixtime - day*86400
local h = math.floor(unixtime/3600)
unixtime = unixtime - h*3600
local m = math.floor(unixtime/60)
unixtime = unixtime - m*60
if returnTable then
return {
year = year,
month = month,
day = day+1,
hour = h,
min = m,
second = unixtime,
}
end
return string.format('%d-%02d-%02d %02d:%02d:%02d',year,month,day+1,h,m,unixtime)
end
--[[
|=========================================================================
| 获取服务器当前时间返回标准格式时间UNIX时间
|=========================================================================
| @return string,int
]]
function datetime.now()
local time = math.floor(UTC_TIME + GameRules:GetGameTime())
return datetime.toDatetime(time),time
end
--[[
|=========================================================================
| 判断星期几,默认当前时间
|=========================================================================
| @param {int} week 区间[1,7]
| @return boolean
]]
function datetime.isWeek(week, datetimeString)
local date = {}
if datetimeString == nil then
date = datetime.toDatetime(math.floor(UTC_TIME + GameRules:GetGameTime()),true)
else
date = datetime.toDatetime(datetime.toUnixTime(datetimeString),true)
end
local y = date.year
local m = date.month
local d = date.day
if m == 1 or m == 2 then
m = m + 12
y = y - 1
end
local w = math.floor((d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) % 7)
if w == 0 then w = 7 end
-- print(currentWeek)
return w == week
end
--[[
|=========================================================================
| 根据日期获取星期几 返回1-7默认当前时间
|=========================================================================
| @param {table} date or string
| @return int
]]
function datetime.getWeek(date)
if date == nil then
local time = math.floor(UTC_TIME + GameRules:GetGameTime())
date = datetime.toDatetime(time,true)
elseif type(date) == "string" then
date = datetime.toDatetime(datetime.toUnixTime(date),true)
end
local y = date.year
local m = date.month
local d = date.day
if m == 1 or m == 2 then
y = y - 1
m = m + 12
end
local w = (d+2*m+math.floor(3*(m+1)/5)+y+math.floor(y/4)-math.floor(y/100)+math.floor(y/400)) % 7 + 1
if w == 0 then
w = 7
end
return w
end
--[[
|=========================================================================
| 判断是否当月最后一天
|=========================================================================
| @return boolean
]]
function datetime.isLastDay(datetimeAny)
local data
if type(datetimeAny) == "string" then
data = datetime.toDatetime(datetime.toUnixTime(datetimeAny), true)
elseif type(datetimeAny) == "table" then
data = datetimeAny
elseif type(datetimeAny) == "number" then
data = datetime.toDatetime(datetimeAny, true)
else
print("Invalid datetime")
end
local i = data.month
if i > 12 or i < 1 then
print("Invalid datetime")
end
if i==1 or i==3 or i==5 or i==7 or i==8 or i==10 or i==12 then
return data.day == 31
elseif i==4 or i==6 or i==9 or i==11 then
return data.day == 30
else
if datetime.isLeapYear(data.year) then
return data.day == 29
else
return data.day == 28
end
end
end
--[[
|=========================================================================
| 获取当月最后一天,传入参数以 yyyy-MM 开头
|=========================================================================
| @return boolean
]]
function datetime.getLastDay(datetimeString)
local i = tonumber(string.sub(datetimeString, 6, 7))
if i==1 or i==3 or i==5 or i==7 or i==8 or i==10 or i==12 then
return 31
elseif i==4 or i==6 or i==9 or i==11 then
return 30
else
if datetime.isLeapYear(tonumber(string.sub(datetimeString, 1, 4))) then
return 29
else
return 28
end
end
end
--[[
|=========================================================================
| 获取增加x个月后的时间一个月按30天计算
|=========================================================================
| @return string
]]
function datetime.addMonth(datetimeString, month)
return datetime.toDatetime(datetime.toUnixTime(datetimeString) + month * 30 * 24 * 3600)
end
--[[
|=========================================================================
| 获取增加x天后的时间
|=========================================================================
| @return string
]]
function datetime.addDay(datetimeString, day)
return datetime.toDatetime(datetime.toUnixTime(datetimeString) + day * 24 * 3600)
end
--[[
|=========================================================================
| 获取两个日期相差多少天,只取日期部分
|=========================================================================
| @return number
]]
function datetime.getDaysByTwoDate(dateStart, dateEnd)
local time1 = datetime.toUnixTime(string.sub(dateStart,1,10).." 00:00:00")
local time2 = datetime.toUnixTime(string.sub(dateEnd,1,10).." 00:00:00")
return math.floor((time2-time1)/(24*3600))
end
--[[
|=========================================================================
| 获取两个日期相差多少秒,结果可用于判定日期前后
|=========================================================================
| @return number
]]
function datetime.subtracte(dateStart, dateEnd)
return datetime.toUnixTime(dateEnd) - datetime.toUnixTime(dateStart)
end
-- ***** datetime 功能结束 ******