全篇以目前主流的 sha-256 哈希算法举例
哈希算法能够将一个字符串(原始数据)转换为另一个字符串(哈希值),举例:
Hello, World! 进行转换后变为 dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f你好 变为 670d9743542cae3ea7ebe36af56bd53648b0a1126162e78d81a32934a711302e1234321 变为 19461b43bbba8a3a4da70703bda96dbc6dcdc2ee78507e34d2bf0f281932fd1f1 变为 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b(空字符串) 变为 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855固定结果
单向性
固定长度输出
雪崩效应
计算快
sha-256 计算很快,饥荒场景里很适合使用根据抽屉原理,不同原始数据可能会产生相同的哈希值。但这个概率极极极极极极低,sha-256 算法还没有公开发现有碰撞的例子,无需担心(其它哈希算法已发现碰撞,如 md5 ,可以去网上搜搜)
我想在模组中写一个VIP名单,但我不希望别人能通过直接看代码的方式来让别人知道VIP具体有谁,那么就可以使用哈希算法
local vips = {
-- 提前写一份转为哈希值的id表
["cb9e7e5c0574707a74488f74a2342e78d3303f5544fb992bb687a6a652cecddf"] = true, -- KU_1234ABCD
["c358271c721e7ba76f30818b75ffd3177d0670955c48217a0bd78ecb5ed7cc8a"] = true, -- KU_AABBCCDD
}
local sha256 = reuiqre("utils/sha-256")
AddPlayerPostInit(function(inst)
if inst then
inst:DoTaskInTime(3, function()
if inst and inst.userid then
-- 将玩家的id转为哈希值,寻找vip列表中是否有同样的哈希值
local is_vip_user = vips[sha256(inst.userid)]
if is_vip_user then
-- 这是vip用户,对他做些什么
end
end
end)
end
end)
lua sha-256库下载(不要直接使用lua文件,如果明文代码的库被篡改那么会直接绕过列表,建议进行混淆处理)
攻击者现在拿到了vip名单,虽然无法直接还原id
但可以通过暴力破解(通常需要几天~几十天时间)的方式,一个个算出所有id的哈希值,并进行匹配,从而拿到id
local vips = {
-- 在原先的基础上加了一个字母后缀 每次更新就变一次
["84fd352eeedf0d59a3c6f9eb270161d5cc6b90ee8ba2c2bdf1a6ccfab5fc675e"] = true, -- KU_1234ABCD_x
["6d39128d8af33ebd47dced977df1533b284f8c1be0bb9ebed03186fb2076e065"] = true, -- KU_AABBCCDD_u
-- 加一些假的vip 永远也算不出id
["3b45470f2c72bb94a028c11d6c200db5b0f07323c173383d10d90834a4fb14ea"] = true, -- 11112222ccccdddd
["6df54fa409dc5920d72b68effa3103818c05c4424c9556df7bf2b2f5e9fe3ab0"] = true, -- kkkkZZZZppppuuuu
}
local sha256 = require("utils/sha-256")
local chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -- 字符后缀每次更新就变一次
local function IsVipUser(userid)
-- 遍历所有字符进行拼接 挨个算一遍
-- 也可以多加几位后缀 但性能会暴涨
for i = 1, #chars do
local char = chars:sub(i, i)
local hash = sha256(userid .. "_" .. char)
if vips[hash] then
return true
end
end
end
AddPlayerPostInit(function(inst)
if inst then
inst:DoTaskInTime(3, function()
if inst and inst.userid then
if IsVipUser(inst.userid) then
-- 这是vip用户,对他做些什么
end
end
end)
end
end)