存档在写入与传输中可能因意外损坏,读档前需要一道完整性判定。校验和的思路:把数据逐字节累加压缩成一个整数指纹,读档时重算比对——指纹对不上即数据损坏。Lua 5.1 无位运算符,选用只用加减乘除取余的 Adler 风格算术校验:两个滚动和 a 与 b 分别对 65521 取余,拼接成 32 位指纹,逐字节成本为常数。
校验和计算与存读接线。示例代码如下:
local function checksum(data)
local a, b = 1, 0
for i = 1, #data do
a = (a + string.byte(data, i)) % 65521
b = (b + a) % 65521
end
return b * 65536 + a
end
写入时随数据存指纹,读取时重算比对。示例代码如下:
local function saveWithSum(slot, blob)
setsysvarex("Blob_" .. slot, blob, 1)
setsysvarex("Sum_" .. slot, checksum(blob), 1)
end
local function loadWithCheck(slot)
local blob = getsysvar("Blob_" .. slot) or ""
local sum = tonumber(getsysvar("Sum_" .. slot)) or 0
if checksum(blob) ~= sum then
return nil
end
return blob
end
1000 字符的校验约 0.2 毫秒(纯算术逐字节循环);比乘法混排的哈希快约 3 倍,实现只有五行。代价是碰撞概率高于加密哈希:适合判定意外损坏,不适合对抗蓄意篡改——算式是公开的,改数据者可以重算指纹。
三个不适用场景:一是防蓄意篡改的场景——指纹算法公开可复算,需引入密钥参与运算才有效力;二是超长数据逐字节成本线性增长——分段各存指纹再汇总比对,控制单次校验时长;三是需要定位损坏位置的场景——指纹只回答"坏没坏",不回答"哪里坏",分段指纹是唯一出路。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【语法】 一、抛坑提问:宠物跟随走直线太生硬,怎么走出圆滑弧线?二次贝塞尔曲线用两个端点加一个控制点,参数从 0 走到 1 …
【游戏】 一、一行代码拆解:SUB[missing] = actual —— 材料替换的全部骨架:替换表声明等价材料对,合成…
【游戏】 一、一行代码拆解:if WINNER == nil then WINNER = actor end —— 抢答判定…
【语法】 一、隐蔽陷阱:技能范围绕施法者旋转,逐点手算坐标容易把余弦与正弦位置写反——二维旋转公式为新横等于旧横乘余弦减旧纵…
【游戏】 一、一行代码拆解:BUYS = BUYS + 1 —— 次数增购的全部骨架:每日 3 次耗尽后可付费增购 1 次,…
【游戏】 一、一行代码拆解:LEND[id] = {who = actor, at = os.time()} —— 仓库借还…