-- [ʞ] rndcbytes.lua
-- ~ lexi hale <lexi@hale.su>
-- © CC0/public domain
-- # requires lua 5.4
-- ? generates random bytes in the form of a maximally
-- compact C string. note that this only works for
-- values small enough to fit into a string literal.
-- > lua rndcbytes.lua <n> <max>
-- <n> is the number of bytes to generate
-- <max> is the number of characters (NOT bytes) to
-- wrap after.
local rnd_srcs = {
'/dev/urandom';
'/dev/random';
}
local rng
for _, r in ipairs(rnd_srcs) do
local ur = io.open(r, 'rb')
if ur then
rng = function(n)
return ur:read(n)
end
break
end
end
if rng == nil then
math.randomseed()
io.stderr:write("WARNING: relying on internal lua RNG. bytes generated are NOT cryptographically reliable!\n")
rng = function(n)
local str = {}
for i = 1,n do
str[i] = string.pack('B', math.random(0,0xff))
end
return table.concat(str)
end
end
local n = 48
local max = 48
if arg[1] then n = tonumber(arg[1]) end
if arg[2] then max = tonumber(arg[2]) end
local bytes = rng(n)
local lns = {}
local cur, chc = {}, 0
local function flush()
if next(cur) then
table.insert(lns, cur)
cur = {}
chc = 0
end
end
local escapes <const> = {
[0x09] = "t";
[0x0a] = "n";
[0x22] = '"';
}
for i=1, #bytes do
local val = bytes:byte(i)
local r
if escapes[val] then
r = '\\' .. escapes[val]
elseif val >= 0x20 and val < 0x7f then
r = string.char(val)
else
r = string.format("\\x%02X", val)
end
if chc + #r > max then flush() end
chc = chc + #r
table.insert(cur, r)
end
flush()
for _, chars in ipairs(lns) do
print(string.format('"%s"', table.concat(chars)))
end