草稿: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