------------------------------------------------------------------------
-- zero-compression zip writer from nullzip.lua ver 0.9.5, by KHMan
------------------------------------------------------------------------
-- Selected Notes:
-- * Note: these notes are for the 4-bit per round lookup xor...
-- * the output is limited to primitive header blocks (no zip64 records)
-- * CRC is disappointingly slow, is there any other way to do it?
-- * writes out data at about 100K/sec on an Athlon 2500+
-- (100 calls to nullzip_test() 4.5K sxw writing test in 10 sec)
------------------------------------------------------------------------
------------------------------------------------------------------------
-- Compute bitwise xor using a 4 bit-at-a-time table lookup. Is there
-- any faster xor-calculating algorithm on vanilla Lua? Or a CRC
-- algorithm that doesn't use (or use fewer) xor (or bitwise) ops?
-- * strings and handling lookups in byte chunks is not faster
-- * a 64K lookup table is 40% faster
-- * a 64K string byte-lookup is 50% faster
-- * building 64K tables is slow, but perhaps can load a binary file...
------------------------------------------------------------------------
CRCLib = {}
local xor_lookup = {}
local idx = 0
for x = 0, 15 do
for y = 0, 15 do
local bz = 1
local xx = x; local yy = y
xor_lookup[idx] = 0
for z = 1, 4 do
if math.mod(xx, 2) ~= math.mod(yy, 2) then
xor_lookup[idx] = xor_lookup[idx] + bz
end
xx = math.floor(xx / 2); yy = math.floor(yy / 2)
bz = bz * 2
end
idx = idx + 1
end
end
local function xor(x, y, size)
local z = 0
local nz = 1
size = size or 8
for n = 1, size do
local nx = math.mod(x, 16); x = (x - nx) / 16
local ny = math.mod(y, 16); y = (y - ny) / 16
z = xor_lookup[nx * 16 + ny] * nz + z
nz = nz * 16
end
return z
end
------------------------------------------------------------------------
-- Straight adaptation of CRC32 code from RFC 1952 (from ISO 3309/ITU-T
-- V.42). The crc should be initialized to zero. Pre- and post-
-- conditioning (one's complement) is performed within
-- nullzip_update_crc so it shouldn't be done by the caller.
------------------------------------------------------------------------
local nullzip_crc_table -- table of CRCs of all 8-bit messages
------------------------------------------------------------------------
-- nullzip_make_crc_table: make the table for a fast CRC.
-- Can be replaced by the precomputed table instead.
-- Usage: crc = nullzip_crc(data)
------------------------------------------------------------------------
local function nullzip_make_crc_table()
local CONST1 = tonumber("EDB88320", 16)
nullzip_crc_table = {}
for n = 0, 255 do
local c = n
for k = 0, 7 do
if math.mod(c, 2) == 1 then
-- c = 0xedb88320L ^ (c >> 1);
c = xor(CONST1, math.floor(c / 2))
else
c = math.floor(c / 2)
end
end
nullzip_crc_table[n] = c
end
end
------------------------------------------------------------------------
-- nullzip_update_crc: update a running crc with a specified buffer
-- Usage: crc = nullzip_update_crc(original_crc, data)
------------------------------------------------------------------------
local function nullzip_update_crc(original_crc, data)
local CONST1 = tonumber("FFFFFFFF", 16)
local c = xor(original_crc, CONST1)
if not nullzip_crc_table then
nullzip_make_crc_table()
end
for n = 1, string.len(data) do
-- c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
c = xor(nullzip_crc_table[xor(c, string.byte(data, n), 2)],
math.floor(c / 256))
end
return xor(c, CONST1)
end
function CRCLib.crc(data)
return nullzip_update_crc(0, data)
end
print(string.format("%x", CRCLib.crc("Guild Test")))
print(string.format("%x", CRCLib.crc("Guild Test")))