[C#] Convert "1,2,3,4,5....,N" to "632,124,364,983, ...., etc".

Started by
23 comments, last by Zahlman 16 years, 1 month ago
I have a need to turn a sequence into apparent randomness, and then be able to turn it back again. For instance, I pass it "1" it returns "636", I pass it "2" it returns "125". And it's completely reversible. I say reverse("636") and I get "1". The range of values for input is in the billions, so simply storing a lookup table isn't going to help. Know of any .NET libraries that are designed for this? So I don't have to go invent my own contraption. =/
Advertisement
It all depends on how apparent you want the randomness to be. XOR is easy, fast, and trivially reversible.
Quote:Original post by Sneftel
It all depends on how apparent you want the randomness to be. XOR is easy, fast, and trivially reversible.


A simple XOR will not give the level of randomness I need. If I'm thinking straight, XOR would give me about B sequential series of consecutive numbers (I don't know if that makes logical sense) where B is the number of bits in the XOR code,

"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,...."

Transforms into:

"100, 500, 400, 101, 501, 401, 102, 502, 402, 103,503,403"

Least, I think this is how it would look...

Edit:/ I cannot believe I'm googling for "reversible randomize function", lol..
You could still use XOR, but add a key-value (like n, the number of input values) to each number in the sequence before and/or after XOR-ing it.
Nick Wilson - Junior C# Developer | See my crappy site
If you don't want consecutive runs, just shuffle the bits afterwards.
You might have better luck searching for "involution"/"involutary function", mathematical terms for a function is its own inverse or "reciprocal cipher" which is the cryptographic term for a encryption method that is its own inverse.
Google search:

http://objectmix.com/c/242647-reversible-random-generator.html

Solution sounds simple and like something you could use.
Is there something useful to you in the System.Security.Cryptography namespace?
I would just have a set pattern you use to switch up bits, then do an XOR to invert some of them.
value 0 0 0 1 0 1 0 1bit   0 1 2 3 4 5 6 7

goes to
value 1 0 0 0 1 0 0 1bit   3 6 2 0 7 1 4 5

then XOR with some mask
10001001 ^ 00101101 -> 10100100

to undo it just do it backward.
XOR with the same mask.encoded    mask10100100 ^ 00101101 -> 10001001

Then reverse the scramble.

That should yield pretty random looking results.

EDIT:
or for even more random like results you could also set the seed of a random number. Use that random seed to generate a random number to do the mask with or even to switch bits with. Then when you save the number save the seed you used in front of the number.
My current game project Platform RPG
I'm still googling around, I'll try 'involution' in my search terms.

Bitwise operations in C# arn't fun.. I made a bug in my code just now, but I don't know if I really want to pursue using my own invention for this:

using System;using System.Collections.Generic;using System.Text;class cBitShuffle{    private const int MyCode = (unchecked((int)0xB00B1EE5));    private static void sSwapBit(ref int TheNumber, int TheLocation1, int TheLocation2)    {        if (!(TheLocation1 >= 0 && TheLocation1 < 32) ||            !(TheLocation2 >= 0 && TheLocation2 < 32))            throw new Exception("Location index must be in range [0..31].");        if (TheLocation1 == TheLocation2) return;        /* Get the bits. */        int TheBit1 = (TheNumber & (1 << TheLocation1)) > 0 ? 1 : 0;         int TheBit2 = (TheNumber & (1 << TheLocation2)) > 0 ? 1 : 0;        /* Clear bits. */        TheNumber &= (int)(0xFFFFFFFF ^ (1 << TheLocation1));        TheNumber &= (int)(0xFFFFFFFF ^ (1 << TheLocation2));        /* Set the bits. */        TheNumber |= TheBit1 << TheLocation2;        TheNumber |= TheBit2 << TheLocation1;    }    static int sEncode(int TheNumber)    {        /* First, NOR it with boobiees. */        TheNumber ^= MyCode;        /* Then swap like a flipflop. */        for (int TheLoop = 0; TheLoop < 32; TheLoop++)            sSwapBit(ref TheNumber, TheLoop, (TheLoop * 3) % 32);        return TheNumber;    }    static int sDecode(int TheNumber)    {        /* First, undo the swaps. */        for (int TheLoop = 0; TheLoop < 32; TheLoop++)            sSwapBit(ref TheNumber, TheLoop, (TheLoop * 3) % 32);        /* Then, undo the NOR it with boobiees. */        TheNumber ^= MyCode;        return TheNumber;    }    static void Main(string[] args)    {        for (int TheLoop = 0; TheLoop < 100; TheLoop++)            Console.WriteLine(TheLoop.ToString() + "\t" + sEncode(TheLoop) + "\t" + sDecode(sEncode(TheLoop)));        Console.ReadKey();    }}

This topic is closed to new replies.

Advertisement