5argon
5argon

Reputation: 3863

Any algorithm that use a number as a feed for generating random string?

I want to generate a random string with any fixed length (N) of my choice. With the same number as a feed to this algorithm it should generate the same string. And with small change to the number like number+1, it should generate a completely different string. (Difficult to relate to the previous seed) It's ok if more than one number might result in the same string. Any approaches for doing this?

By the way, I have a set of characters that I want to appear in the string, like A-Z a-z 0-9.

For example

Algorithm(54893450,4,"ABCDEFG0") -> A0GF
Algorithm(54893451,4,"ABCDEFG0") -> BDCG

I could random each characters one by one, but it would need N different seed for each characters. If I want to do it this way, the question might become "how to generate N numbers from one number" for the seeds.

The end goal is that I want to convert a GUID to something more readable on printed media and shorter. I don't care about conflict. (If the conflict did happen, I can still check the GUID for resolution)

Upvotes: 2

Views: 376

Answers (1)

5argon
5argon

Reputation: 3863

Ok, thanks for the guidance @Jim Mischel. I read all the related pages and come to understand more about this.

http://blog.mischel.com/2017/05/30/how-not-to-generate-unique-codes/

http://blog.mischel.com/2017/06/02/a-broken-unique-key-generator/

http://blog.mischel.com/2017/06/10/how-did-this-happen/

http://blog.mischel.com/2017/06/20/how-to-generate-random-looking-keys/

https://ericlippert.com/2013/11/12/math-from-scratch-part-thirteen-multiplicative-inverses/

https://ericlippert.com/2013/11/14/a-practical-use-of-multiplicative-inverses/

https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm

In short, first I should use a sequential number. That is 1,2,3,4,... Very predictable, but it can turn into something random and hard to guess.

(Note that in my case this is not entirely possible, since each users will be generating his own ID locally so I cannot run a global sequential number, hence I use GUID. But I will make my own workaround to fit GUID to this solution, probably with a simple modulo on the GUID to fit it to my desired range.)

With sequential integer n I can get another seemingly unrelated integer with a multiplication then a modulo. This might looks like (n * x)% m with x and m of my choice. Of course m would have to be larger than the largest number that I want to use since it wraps around the modulo while multiplying.

This alone is a good start as close number n does not provide similar output. But we cannot be so sure about that. For example, if my x is 4 and m is 16 then the input can only produce 0,4,8,12. To avoid this we choose x and m which is a coprime of each other. (Having greatest common divisor of 1) There are many obvious candidate to this such as 100000 as m (defines the limit of my output as 99999) and 2429 as x. If we choose 2 coprime like this, not only the result conflict as less as possible, it also guarantee that each input produces unique output in that range.

We can learn from this example :

(n * 5) % 16

As 5 and 16 is a coprime, we can get a maximum length of sequence of unique numbers before it wraps around. (length = 16) if we input numbers sequentially from 0 to 16 :

Input : 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
Output : 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11, 0

We can see that the output is in a not so predictable sequence and also none of the output other than the last one is the same. It travels to all available number possible.

Now my very predictable sequential running number would produce sufficiently different number and also guarantee not to conflict to any other input as long as it is in the range of m. What's left is to convert this number to a string of my choice via base conversion. If I have 5 characters "ABCDE" then I will use base-5.

Only this is enough for my use case. But with the concept of multiplicative inverse I can also find one more integer y which can reverse that multiply modulo transformation to the original number. Currently I still haven't understand that part fully, but it uses Extended Euclidean Algorithm to find y.

Since my application does not need reverting yet I am fine with not understanding it for now. I will definitely try to understand that part.

Upvotes: 1

Related Questions