[PYTHON] Chiffrement des nombres positifs

Chiffrement des nombres positifs

Crypte les nombres positifs à partir de 0. Si vous spécifiez des nombres qui sont incrémentés docilement comme 1, 2, 3 pour l'ID utilisateur, etc., il sera facile de faire un piratage circulaire, et il prend également en charge les chaînes de caractères aléatoires et les incréments pour empêcher les attaques à tour de rôle en raison d'incréments faciles. La motivation de ce cas est de générer un identifiant. Un exemple d'exécution est présenté ci-dessous.


0 -> 052C5C223627156D7
1 -> 1572257C261D2C376
2 -> 252C1C627627952D3
3 -> 352CEC223627156D7
4 -> 452C1C627627452D3
5 -> 552C1C627627F52D3
6 -> 6512253C662D2C772
7 -> 75D2257C261D2C376
8 -> 8512253C663D2C772
9 -> 953D25C726726C1C2
10 -> A53D258726726C1C2

Comme mentionné ci-dessus, les nombres qui sont simplement incrémentés de 0 à 10 sont convertis en ID crypté comme ça. Ci-dessous, on suppose qu'un ID à 16 chiffres est créé avec une chaîne de caractères hexadécimaux.

Permuter les chiffres en utilisant des nombres premiers

Convertissez le nombre que vous souhaitez chiffrer en chaîne de caractères hexadécimaux et échangez les chiffres en utilisant le reste de l'index de la chaîne de caractères divisé par le nombre premier comme chiffre correspondant.

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
#Chiffre correspondant=> 0, 9, 2, 11, 4 ,13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7

Normalement, la position inférieure commence à partir de la droite et la position gauche est plus grande, mais la lecture aléatoire des chiffres correspondants évite les incréments faciles.

point important

En guise de mise en garde, vous ne pouvez pas sélectionner le même nombre premier que le nombre de chiffres. Si vous souhaitez utiliser un identifiant à 17 chiffres et essayer de mélanger le nombre de chiffres en utilisant 17, tout sera le 0ème chiffre.

>dig = (i * prime) % 16
↓
>dig = (i * 17) % 17
Quelle que soit la valeur de i, dig ne peut être que 0

Remplacement des chaînes hexadécimales par une table de nombres aléatoires

Même si vous mélangez les chiffres, si le nombre de chaque chiffre commence à 0 et se termine par F, vous pouvez estimer l'ID dans une certaine mesure, alors remplacez 0 par F par le résultat du tableau correspondant. Créez un tableau comme celui ci-dessous et faites-le correspondre à chaque chiffre. Je pensais que cela pouvait être automatisé, comme générer dynamiquement une table, mais je ne pouvais penser à aucun autre traitement, alors je l'ai implémenté en incorporant la 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],
]

Code source expérimental


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],
]

#Créer une table inversée pour le déchiffrement
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)
    #Laissez le mod dans l'ID pour le déchiffrement
    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

Résultat d'exécution

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

Omis en chemin

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

À propos de l'utilisation réelle

Plutôt que de l'utiliser tel quel, je pense qu'il est préférable d'insérer une chaîne de caractères factice au hasard tous les 2 à 4. Évitez naturellement d'utiliser la source d'échantillon décrite telle quelle.

Un moyen plus simple et plus simple

En émettant un identifiant à l'avance, vous pouvez éviter d'utiliser une logique compliquée comme celle-ci. Si vous pouvez supposer une limite supérieure telle que «10 000, c'est assez» dans le système que vous essayez de créer, lorsque vous créez et utilisez une table liée de 0 à 9 999 en émettant 10 000 ID à l'avance avec une chaîne de caractères aléatoire Utilisez ce tableau correspondant. En guise de mise en garde, n'oubliez pas d'effectuer une vérification pour vous assurer que votre identifiant est unique.

Déjà probable

Ce type de traitement semble être très demandé, donc je l'ai fait en pensant qu'il semble être dans la bibliothèque existante, mais je ne savais pas quoi dire ce concept et je ne pouvais pas penser à un mot de recherche, alors je l'ai fait moi-même, commenter s'il y a une bibliothèque qui fait la même chose S'il vous plaît dites-moi. c'est tout.

Recommended Posts

Chiffrement des nombres positifs
nombre premier
Numéro de base