草稿:Module:Crc32lua
--[[
LUA 模塊
digest.crc32 - 完全在 Lua 中实现的 CRC-32 校验和。
用法示例
local CRC = require 'digest.crc32lua' print(CRC.crc32 'test') --> 0xD87F7E0C 或 -662733300 assert(CRC.crc32('st', CRC.crc32('te')) == CRC.crc32 'test')
描述
这可以用于计算字符串的 CRC-32 校验和。 这类似于 [1-2]。
API
注意:在下面的函数中,校验和是存储在数字中的 32 位整数。当前数字格式取决于位实现 - 请参见下面的设计说明。
CRC.crc32_byte(byte [, crc]) --> rcrc 返回将字节 `byte` (0..255) 追加到带有 CRC-32 校验和 `crc` 的字符串后的 CRC-32 校验和 `rcrc`。如果省略,则 `crc` 默认为 0(空字符串)。
CRC.crc32_string(s, crc) --> bcrc
返回将字符串 `s` 追加到带有 CRC-32 校验和 `crc` 的字符串后的 CRC-32 校验和 `rcrc`。如果省略,则 `crc` 默认为 0(空字符串)。
CRC.crc32(o, crc) --> bcrc
如果 `o` 是字节,则调用 `crc32_byte`;如果 `o` 是字符串,则调用 `crc32_string`。 CRC.bit 包含模块使用的基础位库。应该将其视为只读副本。
設計說明
当前,此模块在返回的 CRC 校验和中暴露了底层位数组实现。在 BitOp 中,位数组是 32 位有符号整数(可能为负)。在 Lua 5.2 中的 'bit32' 和 'bit.numberlua' 中,位数组是 32 位无符号整数(非负)。这在将来可能会更改,但目前是由于(未经证实的)性能影响而进行的。 在具有 64 位数字的平台上,将 CRC 校验和规范化为无符号的一种方法是执行 `crcvalue % 2^32`。 此模块的名称受 Perl 的 `Digest::CRC*` 启发。
依賴項
需要以下位庫之一: BitOp "bit" -- bitop.luajit.org -- 這在 LuaJIT 中已包含,並且也可用於 Lua 5.1/5.2。這提供了 LuaJIT 中最快的性能。 Lua 5.2 "bit32" -- www.lua.org/manual/5.2 -- 這在 Lua 5.2 中提供,並且在 5.2 中更受歡迎(除非 "bit" 也恰好被安裝)。 "bit.numberlua" (>=000.003) -- https://github.com/davidm/lua-bit-numberlua 這是最慢的,僅用作最後的手段。 它的速度只比 "bit32" 慢幾倍。
下載/安裝
如果使用 LuaRocks: luarocks install lua-digest-crc32lua 否則,下載 <https://github.com/davidm/lua-digest-crc32lua/zipball/master>。 或者,如果使用 git: git clone git://github.com/davidm/lua-digest-crc32lua.git cd lua-digest-crc32lua 可選地解壓縮: ./util.mk 或解壓縮並安裝到 LuaRocks:./util.mk install
參考
[1] http://www.axlradius.com/freestuff/CRC32.java [2] http://www.gamedev.net/reference/articles/article1941.asp [3] http://java.sun.com/j2se/1.5.0/docs/api/java/util/zip/CRC32.html [4] http://www.dsource.org/projects/tango/docs/current/tango.io.digest.Crc32.html [5] http://pydoc.org/1.5.2/zlib.html#-crc32 [6] http://www.python.org/doc/2.5.2/lib/module-binascii.html
許可證
(c) 2008-2011 David Manura。根据与 Lua 相同的条款许可。 在遵守以下条件的情况下,特此授予任何获得此软件及其相关文档文件(“软件”)副本的人免费许可, 可以处理软件,不受限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售 软件的副本,并允许使用软件的人员,但在下列情况下,对软件的副本的所有人和/或相关方 要求:
上述版权声明和本许可声明应包含在所有副本或实质性部分的软件。
本软件按“原样”提供,不提供任何形式的明示或暗示的担保,包括但不限于适销性的担保,对特定用途的适用性和不侵权性。 在任何情况下,作者或版权持有人对任何索赔、损害或其他责任,无论是在合同、侵权行为或其他方式,由软件或软件的使用或其他 处理负责。
(許可證結束) --]]
local M = {_TYPE='module', _NAME='digest.crc32', _VERSION='0.3.20111128'}
local type = type local require = require local setmetatable = setmetatable
--[[
Requires the first module listed that exists, else raises like `require`. If a non-string is encountered, it is returned. Second return value is module name loaded (or ). --]]
local function requireany(...)
local errs = {} for _,name in ipairs{...} do if type(name) ~= 'string' then return name, end local ok, mod = pcall(require, name) if ok then return mod, name end errs[#errs+1] = mod end error(table.concat(errs, '\n'), 2)
end
local bit, name_ = requireany('bit32', 'bit', 'bit.numberlua') local bxor = bit.bxor local bnot = bit.bnot local band = bit.band local rshift = bit.rshift
-- CRC-32-IEEE 802.3 (V.42) local POLY = 0xEDB88320
-- Memoize function pattern (like http://lua-users.org/wiki/FuncTables ). local function memoize(f)
local mt = {} local t = setmetatable({}, mt) function mt:__index(k) local v = f(k); t[k] = v return v end return t
end
-- CRC table. local crc_table = memoize(function(i)
local crc = i for _=1,8 do local b = band(crc, 1) crc = rshift(crc, 1) if b == 1 then crc = bxor(crc, POLY) end end return crc
end)
function M.crc32_byte(byte, crc)
crc = bnot(crc or 0) local v1 = rshift(crc, 8) local v2 = crc_table[bxor(crc % 256, byte)] return bnot(bxor(v1, v2))
end local M_crc32_byte = M.crc32_byte
function M.crc32_string(s, crc)
crc = crc or 0 for i=1,#s do crc = M_crc32_byte(s:byte(i), crc) end return crc
end local M_crc32_string = M.crc32_string
function M.crc32(s, crc)
if type(s) == 'string' then return M_crc32_string(s, crc) else return M_crc32_byte(s, crc) end
end
M.bit = bit -- bit library used
return M