0

I'm currently working on a Lua port of the Library Of Babel.

To my knowledge, it works by randomly generating the title and book by using the Hex, Bookshelf, Shelf, and Volume numbers. To implement this in Lua, I was using randomlua, because Lua's built-in random API wasn't working well for me.

My only problem with it so far is that it doesn't allow me to reverse a result from the LCG to get the seed, which I need to do to implement searching for books. I'm not that intelligent when it comes to math like this, so I have no idea where to start.

This is the code for generating random numbers:

linear_congruential_generator = {}
linear_congruential_generator.__index = linear_congruential_generator

function linear_congruential_generator:random(a, b)
    local y = (self.a * self.x + self.c) % self.m
    self.x = y
    if not a then return y / 0x100000000
    elseif not b then
        if a == 0 then return y
        else return 1 + (y % a) end
    else
        return a + (y % (b - a + 1))
    end
end

I have absolutely no idea how I could reverse the function to make it return a seed where that result occurs. Any help on this is greatly appreciated.

This is how I calculate the Title and Contents of a page:

local charset = {}  do -- [0-9a-zA-Z]
    for c = 48, 57  do table.insert(charset, string.char(c)) end
    for c = 65, 90  do table.insert(charset, string.char(c)) end
    for c = 97, 122 do table.insert(charset, string.char(c)) end
    table.insert(charset," ")
end
function randomString(length)
    if not length or length <= 0 then return '' end
    return randomString(length - 1) .. charset[generator:random(1, #charset)]
end

It's 8 characters for the Title, and 3200 Characters for the contents.

  • To calculate the initial seed after N invocations of random(), you have to move backwards N times. What parameters do you use in LCG: ansi/nr/mvc ? – Egor Skriptunoff Jun 14 '20 at 09:06
  • @EgorSkriptunoff I just added it to the original post, that's the only time I randomly generate a number in the code. The charset has 63 characters, so the parameters are `:random(1,63)` – Christian Fletcher Jun 14 '20 at 19:12
  • Where do you initialize `self.a`, `self.c` and `self.m`? – Egor Skriptunoff Jun 14 '20 at 19:16
  • You can see the full script in the [randomlua](https://github.com/linux-man/randomlua/blob/master/randomlua.lua) github, I didn't modify it whatsoever. ```lua function lcg(s, r) local temp = {} setmetatable(temp, linear_congruential_generator) temp.a, temp.c, temp.m = 1103515245, 12345, 0x100000000 --from Ansi C if r then if r == 'nr' then temp.a, temp.c, temp.m = 1664525, 1013904223, 0x100000000 --from Numerical Recipes. elseif r == 'mvc' then temp.a, temp.c, temp.m = 214013, 2531011, 0x100000000 end--from MVC end temp:randomseed(s) return temp end ``` @EgorSkriptunoff – Christian Fletcher Jun 14 '20 at 19:33
  • Yes, there are three variants of the LCG there. Which one do you use? – Egor Skriptunoff Jun 14 '20 at 20:02
  • @EgorSkriptunoff I am using the Linear Congruential Generator, not the Multiply With Carry or the Mersenne twister. – Christian Fletcher Jun 14 '20 at 20:09
  • What are the arguments you pass for `lcg()` when you initialize the generator? – Egor Skriptunoff Jun 14 '20 at 23:07
  • @EgorSkriptunoff, I am using lcg(0) to initialize. – Christian Fletcher Jun 15 '20 at 00:46
  • This means your seed is `0` :-) What is your Lua version? – Egor Skriptunoff Jun 15 '20 at 01:09
  • Thats not the problem, the seed isn't always 0. I set the seed manually based on the Room, Wall, Shelf, and Volume. So when I generate books, their seeds will be different to generate a different string. What I'm trying to do is take a result, give it to the function, and I'll get a seed where that result will occur, basically the searching in the Library Of Babel. I'm using Lua 5.1. @EgorSkriptunoff – Christian Fletcher Jun 15 '20 at 01:25
  • In Lua 5.1 your LCG is not reversible because you have changed constant `0x10000` to `0x100000000`. Lua 5.1 can't exactly multiply two 32-bit numbers. – Egor Skriptunoff Jun 15 '20 at 05:00
  • That must have been a typo, would it still be impossible to reverse if I fixed that or no? – Christian Fletcher Jun 15 '20 at 05:09
  • Yes. To make one step back: `x=(12345-x)*5275%0x10000` – Egor Skriptunoff Jun 15 '20 at 11:22

0 Answers0