Encrypts positive numbers starting from 0. If you specify numbers that are incremented obediently as 1, 2, 3 for user ID etc., it will be easy to do brute force hacking. The motivation for this case is to generate an ID. An execution example is shown below.
0 -> 052C5C223627156D7
1 -> 1572257C261D2C376
2 -> 252C1C627627952D3
3 -> 352CEC223627156D7
4 -> 452C1C627627452D3
5 -> 552C1C627627F52D3
6 -> 6512253C662D2C772
7 -> 75D2257C261D2C376
8 -> 8512253C663D2C772
9 -> 953D25C726726C1C2
10 -> A53D258726726C1C2
As mentioned above, the numbers that are just incremented from 0 to 10 are converted to the encrypted ID like that. Below, it is assumed that a 16-digit ID is created with a hexadecimal character string.
Convert the number you want to encrypt to a hexadecimal character string, and exchange the digits using the remainder of the index of the character string divided by the prime number as the corresponding digit.
n = 9999
PrimeTable = [61, 31, 53, 29, 37, 5, 23, 47, 7, 59, 43, 3, 17, 13, 19, 41, 11]
mod = n % 16 # mod = 15
mod = int(enc[0], 16)
prime = PrimeTable[mod] # prime = 41
for i in range(16):
dig = (i * prime) % 16
#Corresponding digit=> 0, 9, 2, 11, 4 ,13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7
Normally, the lower position starts from the right and the large position starts on the left, but shuffling the corresponding digits avoids easy increments.
As a caveat, you may not select the same prime number as the number of digits. If you want to use a 17-digit ID and try to shuffle the number of digits using 17, all will be the 0th digit.
>dig = (i * prime) % 16
↓
>dig = (i * 17) % 17
Whatever the value of i, dig can only be 0
Even if you shuffle the digits, if the number of each digit starts from 0 and ends with F, you can estimate the ID to some extent, so replace 0 to F with the result of the corresponding table. Create a table like the one below and make it correspond to each digit. I thought it would be possible to automate things such as dynamically generating a table, but I couldn't think of any further processing, so I implemented it by embedding the table.
digitsTable = [
[5, 3, 15, 14, 11, 7, 6, 2, 12, 8, 10, 13, 4, 1, 9, 0],
[6, 5, 13, 7, 15, 11, 14, 12, 0, 8, 2, 9, 3, 4, 1, 10],
[7, 0, 11, 15, 2, 13, 12, 6, 4, 10, 9, 5, 1, 3, 14, 8],
[3, 6, 13, 7, 5, 10, 14, 0, 1, 9, 15, 4, 11, 8, 2, 12],
[12, 10, 2, 3, 4, 5, 6, 15, 7, 11, 13, 0, 14, 9, 1, 8],
[2, 10, 13, 14, 0, 1, 12, 6, 3, 15, 11, 5, 9, 7, 8, 4],
[13, 8, 9, 14, 0, 15, 1, 3, 2, 11, 5, 12, 7, 4, 10, 6],
[1, 10, 15, 7, 14, 6, 12, 11, 2, 8, 4, 5, 13, 0, 9, 3],
[6, 4, 7, 1, 12, 8, 10, 0, 15, 14, 9, 13, 5, 11, 3, 2],
[2, 14, 13, 15, 6, 11, 10, 7, 3, 8, 1, 4, 5, 0, 9, 12],
[12, 4, 2, 5, 10, 3, 0, 11, 8, 14, 13, 1, 7, 6, 15, 9],
[7, 1, 14, 5, 0, 2, 9, 12, 8, 6, 4, 3, 11, 10, 15, 13],
[5, 8, 4, 2, 11, 10, 7, 14, 3, 0, 12, 6, 9, 13, 1, 15],
[2, 4, 14, 13, 15, 10, 7, 6, 9, 11, 1, 0, 12, 3, 8, 5],
[2, 14, 9, 11, 5, 3, 6, 1, 12, 13, 8, 4, 15, 7, 0, 10],
[5, 7, 9, 14, 4, 15, 2, 13, 3, 12, 8, 1, 10, 6, 11, 0],
]
digitsTable = [
[5, 3, 15, 14, 11, 7, 6, 2, 12, 8, 10, 13, 4, 1, 9, 0],
[6, 5, 13, 7, 15, 11, 14, 12, 0, 8, 2, 9, 3, 4, 1, 10],
[7, 0, 11, 15, 2, 13, 12, 6, 4, 10, 9, 5, 1, 3, 14, 8],
[3, 6, 13, 7, 5, 10, 14, 0, 1, 9, 15, 4, 11, 8, 2, 12],
[12, 10, 2, 3, 4, 5, 6, 15, 7, 11, 13, 0, 14, 9, 1, 8],
[2, 10, 13, 14, 0, 1, 12, 6, 3, 15, 11, 5, 9, 7, 8, 4],
[13, 8, 9, 14, 0, 15, 1, 3, 2, 11, 5, 12, 7, 4, 10, 6],
[1, 10, 15, 7, 14, 6, 12, 11, 2, 8, 4, 5, 13, 0, 9, 3],
[6, 4, 7, 1, 12, 8, 10, 0, 15, 14, 9, 13, 5, 11, 3, 2],
[2, 14, 13, 15, 6, 11, 10, 7, 3, 8, 1, 4, 5, 0, 9, 12],
[12, 4, 2, 5, 10, 3, 0, 11, 8, 14, 13, 1, 7, 6, 15, 9],
[7, 1, 14, 5, 0, 2, 9, 12, 8, 6, 4, 3, 11, 10, 15, 13],
[5, 8, 4, 2, 11, 10, 7, 14, 3, 0, 12, 6, 9, 13, 1, 15],
[2, 4, 14, 13, 15, 10, 7, 6, 9, 11, 1, 0, 12, 3, 8, 5],
[2, 14, 9, 11, 5, 3, 6, 1, 12, 13, 8, 4, 15, 7, 0, 10],
[5, 7, 9, 14, 4, 15, 2, 13, 3, 12, 8, 1, 10, 6, 11, 0],
]
#Create a reverse lookup table for decryption
digitsReverseTable = []
for tbl in digitsTable:
a = [0] * 16
for i, v in enumerate(tbl):
a[v] = i
digitsReverseTable.append(a)
PrimeTable = [61, 31, 53, 29, 37, 5, 23, 47, 7, 59, 43, 3, 17, 13, 19, 41, 11]
def encodeNumber(n):
hexStr = "00000000000000000000" + "{:X}".format(n)
hexStr = hexStr[-16:]
mod = n % 16
prime = PrimeTable[mod]
enc = [""] * 16
for i in range(16):
c = hexStr[i]
dig = (i * prime) % 16
idx = int(c, 16)
m = digitsTable[i][idx]
enc[dig] = "{:X}".format(m)
#Leave the mod in the ID for decryption
return "{:X}".format(mod) + "".join(enc)
def decodeNumber(enc):
mod = int(enc[0], 16)
prime = PrimeTable[mod]
enc = enc[1:]
numArr = [0] * 16
for i in range(16):
dig = (i * prime) % 16
ridx = int(enc[dig], 16)
m = digitsReverseTable[i][ridx]
numArr[i] = m
numArr = list(reversed(numArr))
n = 0
for i in range(16):
n += numArr[i] * 16 ** i
return n
def main():
for i in range(0, 100):
enc = encodeNumber(i)
print(i, enc, decodeNumber(enc))
if __name__ == "__main__":
main()
# python encode_counter.py
0 052C5C223627156D7 0
1 1572257C261D2C376 1
2 252C1C627627952D3 2
3 352CEC223627156D7 3
4 452C1C627627452D3 4
5 552C1C627627F52D3 5
6 6512253C662D2C772 6
7 75D2257C261D2C376 7
8 8512253C663D2C772 8
9 953D25C726726C1C2 9
10 A53D258726726C1C2 10
11 B57D651726322C1C2 11
12 C5673C2D162C7522A 12
13 D52C6C223627156D7 13
Omitted on the way
89 953D25C726736C1C2 89
90 A53D258726736C1C2 90
91 B57D651726332C1C2 91
92 C5673C2D162C7523A 92
93 D52C6C233627156D7 93
94 E57D651726332CBC2 94
95 F5277C2D066C35231 95
96 052C5C263627156D7 96
97 1576257C261D2C376 97
98 252C1C667627952D3 98
99 352CEC263627156D7 99
I think that it is better to randomly insert a dummy character string every 2 to 4 characters rather than using it as it is, but of course, avoid using the sample source described as it is.
By issuing an ID in advance, you can avoid using complicated logic like this case. If you can assume the upper limit such as "10,000 is enough" in the system you are trying to create, when you create and use a table linked to 0 to 9999 by issuing 10,000 IDs in advance with a random character string Use that corresponding table. As a caveat, don't forget to perform a check to ensure that your ID is unique.
This kind of processing seems to be in high demand, so I made it while thinking that it seems to be in the existing library, but I did not know what to say this concept and I could not think of a search word, so I made it myself, comment if there is a library that does the same thing Please tell me. that's all.