Symmetric Bijective Algorithm for Integers

后端 未结 11 848
甜味超标
甜味超标 2020-12-01 03:33

I need an algorithm that can do a one-to-one mapping (ie. no collision) of a 32-bit signed integer onto another 32-bit signed integer.

My real concern is enough entr

相关标签:
11条回答
  • 2020-12-01 04:17

    Take a number, multiplies by 9, inverse digits, divide by 9.

    123  <> 1107 <> 7011 <> 779
    256  <> 2304 <> 4032 <> 448
    1028 <> 9252 <> 2529 <> 281
    

    Should be obscure enough !!

    Edit : it is not a bijection for 0 ending integer

    900 <> 8100 <> 18 <> 2
    2   <> 18   <> 81 <> 9
    

    You can always add a specific rule like : Take a number, divide by 10 x times, multiplies by 9, inverse digits, divide by 9, multiples by 10^x.

    And so

    900 <> 9 <> 81 <> 18 <> 2 <> 200
    200 <> 2 <> 18 <> 81 <> 9 <> 900
    

    W00t it works !

    Edit 2 : For more obscurness, you can add an arbitrary number, and substract at the end.

    900 < +256 > 1156 < *9 > 10404 < invert > 40401 < /9 > 4489 < -256 > 4233
    123 < +256 > 379 < *9 > 3411 < invert > 1143 < /9 > 127 < -256 > -129
    
    0 讨论(0)
  • 2020-12-01 04:19

    Can you use a random generated lookup-table? As long as the random numbers in the table are unique, you get a bijective mapping. It's not symmetric, though.

    One 16 GB lookup-table for all 32 bit values is probably not practical, but you could use two separate 16-bit lookup tables for the high-word and the low word.

    PS: I think you can generate a symmetric bijective lookup table, if that's important. The algorithm would start with an empty LUT:

    +----+        +----+
    |  1 |   ->   |    |
    +----+        +----+
    |  2 |   ->   |    |
    +----+        +----+
    |  3 |   ->   |    |
    +----+        +----+
    |  4 |   ->   |    |
    +----+        +----+
    

    Pick the first element, assign it a random mapping. To make the mapping symmetric, assign the inverse, too:

    +----+        +----+
    |  1 |   ->   |  3 |
    +----+        +----+
    |  2 |   ->   |    |
    +----+        +----+
    |  3 |   ->   |  1 |
    +----+        +----+
    |  4 |   ->   |    |
    +----+        +----+
    

    Pick the next number, again assign a random mapping, but pick a number that's not been assigned yet. (i.e. in this case, don't pick 1 or 3). Repeat until the LUT is complete. This should generate a random bijective symmetric mapping.

    0 讨论(0)
  • 2020-12-01 04:23

    Apart from generating random lookup-tables, you can use a combination of functions:

    • XOR
    • symmetric bit permutation (for example shift 16 bits, or flip 0-31 to 31-0, or flip 0-3 to 3-0, 4-7 to 7-4, ...)
    • more?
    0 讨论(0)
  • 2020-12-01 04:25

    Draw a large circle on a large sheet of paper. Write all the integers from 0 to MAXINT clockwise from the top of the circle, equally spaced. Write all the integers from 0 to MININT anti-clockwise, equally spaced again. Observe that MININT is next to MAXINT at the bottom of the circle. Now make a duplicate of this figure on both sides of a piece of stiff card. Pin the stiff card to the circle through the centres of both. Pick an angle of rotation, any angle you like. Now you have a 1-1 mapping which meets some of your requirements, but is probably not obscure enough. Unpin the card, flip it around a diameter, any diameter. Repeat these steps (in any order) until you have a bijection you are happy with.

    If you have been following closely it shouldn't be difficult to program this in your preferred language.

    For Clarification following the comment: If you only rotate the card against the paper then the method is as simple as you complain. However, when you flip the card over the mapping is not equivalent to (x+m) mod MAXINT for any m. For example, if you leave the card unrotated and flip it around the diameter through 0 (which is at the top of the clock face) then 1 is mapped to -1, 2 to -2, and so forth. (x+m) mod MAXINT corresponds to rotations of the card only.

    0 讨论(0)
  • 2020-12-01 04:28

    Here is my simple idea: You can move around the bits of the number, as PeterK proposed, but you can have a different permutation of bits for each number, and still be able to decipher it.

    The cipher goes like this: Treat the input number as an array of bits I[0..31], and the output as O[0..31]. Prepare an array K[0..63] of 64 randomly generated numbers. This will be your key. Take the bit of input number from position determined by the first random number (I[K[0] mod 32]) and place it at the beginning of your result (O[0]). Now to decide which bit to place at O[1], use the previously used bit. If it is 0, use K[1] to generate position in I from which to take, it it is 1, use K[2] (which simply means skip one random number).

    Now this will not work well, as you may take the same bit twice. In order to avoid it, renumber the bits after each iteration, omitting the used bits. To generate the position from which to take O[1] use I[K[p] mod 31], where p is 1 or 2, depending on the bit O[0], as there are 31 bits left, numbered from 0 to 30.

    To illustrate this, I'll give an example:

    We have a 4-bit number, and 8 random numbers: 25, 5, 28, 19, 14, 20, 0, 18.

    I: 0111    O: ____
        _
    

    25 mod 4 = 1, so we'll take bit whose position is 1 (counting from 0)

    I: 0_11    O: 1___
         _
    

    We've just taken a bit of value 1, so we skip one random number and use 28. There are 3 bits left, so to count position we take 28 mod 3 = 1. We take the first (counting from 0) of the remaining bits:

    I: 0__1    O: 11__
       _
    

    Again we skip one number, and take 14. 14 mod 2 = 0, so we take the 0th bit:

    I: ___1    O: 110_
          _
    

    Now it doesn't matter, but the previous bit was 0, so we take 20. 20 mod 1 = 0:

    I: ____    O: 1101
    

    And this is it.

    Deciphering such a number is easy, one just has to do the same things. The position at which to place the first bit of the code is known from the key, the next positions are determined by the previously inserted bits.

    This obviously has all the disadvantages of anything which just moves the bits around (for example 0 becomes 0, and MAXINT becomes MAXINT), but is seems harder to find how someone has encrypted the number without knowing the key, which has to be secret.

    0 讨论(0)
提交回复
热议问题