In einem bestimmten Dienst werden Benutzer-IDs fortlaufend mit ganzen Zahlen nummeriert, und wenn die Benutzer-ID dem Benutzer angezeigt wird, wird die Anzahl der Benutzer vorhergesagt, wenn sie dem Benutzer so angezeigt wird, wie sie ist. Daher möchte ich die Benutzer-ID in eine andere Ganzzahl konvertieren und dem Benutzer den Wert anzeigen.
Wenn ich einen Serienschlüssel veröffentliche, der nur aus ganzen Zahlen in einer Zeitschrift usw. besteht, möchte ich zufällig einen Serienschlüssel generieren. Mit zunehmender Anzahl wird jedoch eine große Menge an Ressourcen durch doppelte Überprüfung verbraucht. Daher möchten wir eine Ganzzahl mit Seriennummer reversibel in eine andere Ganzzahl konvertieren und diesen Wert als Serienschlüssel verwenden.
Reversibles Verwürfeln von ganzen Zahlen - C schärft Sie
In Anlehnung an die Weisheit unserer Vorgänger werden wir eine vollständig monomorphe Konvertierungsfunktion in Python implementieren.
scramble.py
def scramble(number, salt, inverse_salt):
"""
Zahlen ineinander umwandeln.
:param int number:Ganzzahl, die konvertiert werden soll
:param int salt:Ganzzahl, die der Schlüssel zur Konvertierung ist
:param int inverse_salt:2 der Ganzzahlen, die der Schlüssel zur Konvertierung sind^Inverse Zahl Modulo 32
:return:Konvertierte Ganzzahl
"""
_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
Ich wusste nicht, wie ich die inverse Zahl einfach berechnen kann. Als ich im Firmenchat @melponn konsultierte, wurde der folgende Artikel vorgestellt. Modular multiplicative inverse function in Python - Stack Overflow
Der Konvertierungsschlüssel wird zufällig bestimmt und seine Umkehrung wird durch die erweiterte euklidische Methode der gegenseitigen Teilung berechnet.
generate.py
import random
class InverseDoesNotExist(Exception):
pass
def generate_salt():
"""
Salz und Inverse in Rührei verwendet_Salz erzeugen.
: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
Beachten Sie Folgendes, wenn Sie es mit einem Seriencode eines Magazins verwenden.
Recommended Posts