Skip to content

Instantly share code, notes, and snippets.

@TheIndra55
Created March 15, 2023 01:13
Show Gist options
  • Select an option

  • Save TheIndra55/d9843ec9f66c5f9c0365bd40dba5f417 to your computer and use it in GitHub Desktop.

Select an option

Save TheIndra55/d9843ec9f66c5f9c0365bd40dba5f417 to your computer and use it in GitHub Desktop.
--- @param name string
function calculateHash(name)
name = name:lower()
local hash = 0xffffffff
for c = 1, name:len() do
local char = name:byte(c)
hash = hash ~ ((char << 24) & 0xffffffff)
for i = 1, 8 do
if (hash & 0x80000000) ~= 0 then
hash = ((hash << 1) & 0xffffffff) ~ 0x4C11DB7;
else
hash = (hash << 1) & 0xffffffff;
end
end
end
return (~hash) & 0xffffffff
end
local bigfile = io.open("bigfile.000", "wb")
local files = {}
if bigfile == nil then
print("Failed to open output file bigfile")
return
end
-- write number of files
bigfile:write(string.pack("<I", #arg))
-- order files by hash order
for _, file in ipairs(arg) do
local hash = calculateHash(file)
table.insert(files, { hash = hash, name = file })
end
table.sort(files, function (a, b)
return a.hash < b.hash
end)
-- write lookup table/hashes
for _, file in ipairs(files) do
bigfile:write(string.pack("<I", file.hash))
end
-- skip over file entries
bigfile:seek("cur", #files * 16)
-- write files
for _, file in ipairs(files) do
local f = io.open(file.name, "rb")
local cursor = bigfile:seek()
-- get next aligned offset
while (cursor & 2047) ~= 0 do cursor = cursor + 1 end
bigfile:seek("set", cursor)
bigfile:write(f:read("a"))
f:close()
file.position = cursor
file.size = bigfile:seek() - cursor
end
-- correct header
bigfile:seek("set", 4 + #files * 4)
for _, file in ipairs(files) do
bigfile:write(string.pack("<IIII", file.size, file.position >> 11, 0xffffffff, 0))
end
bigfile:close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment