Dans un certain service, les ID utilisateur sont numérotés séquentiellement avec des entiers, et lors de l'affichage de l'ID utilisateur à l'utilisateur, s'il est montré à l'utilisateur tel quel, le nombre d'utilisateurs sera prédit. Par conséquent, je voudrais convertir l'ID utilisateur en un autre entier et montrer la valeur à l'utilisateur.
Lors de la publication d'une clé de série constituée uniquement de nombres entiers dans un magazine, etc., je souhaite générer une clé de série au hasard, mais à mesure que le nombre augmente, une grande quantité de ressources est consommée par la vérification des doublons. Par conséquent, nous voulons convertir de manière réversible un entier de numéro de série en un autre entier et utiliser cette valeur comme clé de série.
Brouillage réversible d'entiers - C vous aiguisé
Empruntant la sagesse de nos prédécesseurs, nous implémentons une fonction de conversion complète en Python.
scramble.py
def scramble(number, salt, inverse_salt):
"""
Convertir les nombres les uns aux autres.
:param int number:Entier à convertir
:param int salt:Entier qui est la clé de la conversion
:param int inverse_salt:2 des entiers qui sont la clé de la conversion^Nombre inverse modulo 32
:return:Entier converti
"""
_assert_number(number)
_assert_salt(salt, inverse_salt)
return _trim32bit(_reverse32bit(_trim32bit(number * salt)) * inverse_salt)
def _assert_number(number):
assert 1 <= number <= 0xFFFFFFFF
def _assert_salt(salt, inverse_salt):
assert _trim32bit(salt * inverse_salt) == 1
def _reverse32bit(number):
number = ((number >> 1) & 0x55555555) | ((number & 0x55555555) << 1)
number = ((number >> 2) & 0x33333333) | ((number & 0x33333333) << 2)
number = ((number >> 4) & 0x0F0F0F0F) | ((number & 0x0F0F0F0F) << 4)
number = ((number >> 8) & 0x00FF00FF) | ((number & 0x00FF00FF) << 8)
number = (number >> 16) | (number << 16)
return number
def _trim32bit(number):
return number & 0xFFFFFFFF
Je ne savais pas comment calculer facilement le nombre inverse, alors quand j'ai consulté @melponn dans le chat de l'entreprise, l'article suivant a été présenté. Modular multiplicative inverse function in Python - Stack Overflow
La clé de conversion est déterminée aléatoirement et son inverse est calculé par la méthode de division mutuelle euclidienne étendue.
generate.py
import random
class InverseDoesNotExist(Exception):
pass
def generate_salt():
"""
Sel et inverse utilisés dans le brouillage_Générer du sel.
:return: salt, inverse_salt
"""
salt = _gen_salt()
return salt, _modinv(salt, 0x100000000)
def _gen_salt():
salt = random.randint(3, 0xFFFFFFFF)
if salt % 2 == 0:
salt += 1
return salt
def _egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = _egcd(b % a, a)
return (g, x - (b // a) * y, y)
def _modinv(a, m):
g, x, y = _egcd(a, m)
if g != 1:
raise InverseDoesNotExist()
else:
return x % m
test.py
salt, inverse_salt = generate_salt()
def f(number):
return scramble(number, salt, inverse_salt)
for n in xrange(1, 0xFFFFFFFF):
assert f(f(n)) == n
Lorsque vous l'utilisez avec le code de série d'un magazine, tenez compte de ce qui suit.
Recommended Posts