Trouble generating string-based seeds

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
leNoah
Prole
Posts: 14
Joined: Mon Feb 08, 2016 5:00 pm

Trouble generating string-based seeds

Post by leNoah » Tue Oct 31, 2017 9:40 pm

Hello everyone,
I've been experimenting with random generation, and seed-based stuff. I'm not really sure of the best way to do this, previously I just called love.math.setRandomSeed(seed) in love.load.
What I want to do is let the user input a string that can be used for a string. Currently, I have this function:

Code: Select all

function generateSeed(seed)
  seedStringOfNumbers = ""
  
  for i = 1, string.len(seed) do
    seedStringOfNumbers = seedStringOfNumbers .. tostring(string.byte(string.sub(seed, i, i)))
  end
  print(seedStringOfNumbers)

  return(seedStringOfNumbers)
  --love.math.setRandomSeed(tonumber(seedStringOfNumbers))
end
The problem is, almost any seed i put in is too big, and just sets the seed to 0!
I'm really not sure how to fix this, I'd be really grateful for any help.

Thanks in advance,
Noah :)
--Home is where the heart is. Home is the ribcage.--

User avatar
Azhukar
Party member
Posts: 478
Joined: Fri Oct 26, 2012 11:54 am

Re: Trouble generating string-based seeds

Post by Azhukar » Wed Nov 01, 2017 12:13 am

Repeated string concatenation produces a lot of garbage for the garbage collector, work with bytes or use table.concat

Here's a very bad string hashing function

Code: Select all

local maxSeed = 2^30
local function stringToSeed(s)
	local seed = 1
	for i=1,s:len() do
		seed = (seed*31337 + s:byte(i))%maxSeed
	end
	return seed
end

User avatar
zorg
Party member
Posts: 2983
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Trouble generating string-based seeds

Post by zorg » Wed Nov 01, 2017 8:34 am

The problem is that the way you're doing it, each character will take up either 2 or 3 digits, and the numbers in lua have ~15 decimal digit precision at the very least. That means your strings will have to be limited to 15/2 or 15/3, or 4-5 characters.

That's not how seed strings work, usually.

As Azhukar said above me, people need to use a hash function, that converts an any-sized string into a constant-sized number (or array of bits, whichever you prefer to call it); in our case, löve's random generators can either use one number, or two 32-bit integers (i'm assuming, the wiki doesn't say but it is kinda self-evident) for a 64-bit seed value. The hash function could go for the latter.

A good hash function mixes all bits of the input into all bits of the output, and the next löve version will include a few types:
* Added love.data module. It includes hex/base64 encoding functions, MD5 and SHA hashing, string packing, and more.
For now, you can use Azhukar's, though i do suggest an edited version:

Code: Select all

local maxSeed = 2^32
local function stringToSeed(s)
	local seedlo, seedhi = 1, 1
	for i=1,s:len() do
		seedlo = (seedhi * 31337 + s:byte(            i)) % maxSeed
		seedhi = (seedlo * 31337 - s:byte((s:len()+1)-i)) % maxSeed
	end
	return seedlo, seedhi
end
And you just pass the function into the setRandomSeed function, and it'll use both numbers to set the seed.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

Post Reply

Who is online

Users browsing this forum: No registered users and 24 guests