I wanted to reversibly convert a numerical value with an arbitrary number of digits, and when I searched variously, I found the following articles of great ancestors. Reversible scrambling of integers --C Sharpens you up Reversible scrambling of integers in Python
Changed so that the digit part can be received as an argument. It seems that the bit-reversal part cannot be realized well unless it is a multiplier of 2. (Maybe I didn't find out enough) The reverse part was a little cut off.
scramble.py
# -*- coding: utf-8 -*-
"""
Digit-free reversible integer creation
"""
class Scramble:
def __init__(self, bit_digit):
self.__bit_digit = bit_digit
self.__mask = (1 << bit_digit) - 1
def scramble(self, number, salt, inverse_salt):
return self.__trim(self.__reverse(self.__trim(number * salt)) * inverse_salt)
def __reverse(self, number):
bit = '0' * self.__bit_digit + bin(number)[2:]
bit = bit[-self.__bit_digit:]
bit = ''.join(reversed(list(bit)))
return long(bit, 2)
def __trim(self, number):
return number & self.__mask
def scramble(number, bit_digit, salt, inverse_salt):
return Scramble(bit_digit).scramble(number, salt, inverse_salt)
When you actually use it
from scramble import scramble
print scramble(1, 48, 0x717b9f2dded3, 0xb784b8b6295b)
>> 186674888497786L
print scramble(186674888497786L, 48, 0x717b9f2dded3, 0xb784b8b6295b
>> 1
It was converted reversibly like this.
If number is 48bit, salt and inverse_salt should also be 48bit.
Recommended Posts