Golf de hachage cryptographique (voleurs)

12

Ce concours est terminé.

Il n'y a pas de réponse crackable restante dans le défi des flics.

Fil d'accompagnement du golf de hachage cryptographique

Pour rappel, voici les règles pour les voleurs du défi principal:

Tâche

Crack quelconque des cops d'arguments en affichant la suivante dans les voleurs de la discussion: deux messages M et N en I de telle sorte que H (M) = H (N) et M ≠ N .

Notation

Cracking chaque soumission de flic vous gagne un point. Le voleur avec le plus de points gagne.

En cas d'égalité, le voleur à égalité qui a réussi la soumission la plus longue gagne.

Règles supplémentaires

  • Chaque soumission de flic ne peut être piratée qu'une seule fois.

  • Si une soumission de flic repose sur un comportement défini ou non défini par l'implémentation, il vous suffit de trouver une fissure qui fonctionne (de manière vérifiable) sur votre machine.

  • Chaque fissure appartient à une réponse distincte dans le fil des voleurs.

  • La publication d'une tentative de craquage invalide vous interdit de craquer cette soumission particulière pendant 30 minutes.

  • Vous ne pouvez pas casser votre propre soumission.

Exemple

Python 2.7, 22 octets par user8675309

1

et

18

Classement

  1. eBusiness: 3 fissures, 393 octets
  2. Martin Büttner: 3 fissures, 299 octets
  3. jimmy23013: 3 fissures, 161 octets
  4. Sp3000: 3 fissures, 44 octets
  5. tucuxi: 2 fissures, 239 octets
  6. Vi .: 2 fissures, 87 octets
  7. feersum: 1 fissure, 216 octets
  8. mathmandan: 1 fissure, 139 octets
  9. ossifrage squeamish: 1 fissure, 134 octets
Dennis
la source

Réponses:

5

C, 122 octets - par: M. Llama

bmaj8PCosFLAJjeHaevvvchnJedmg2iujpePOPivI2x2asw0yKa2eA15xvFJMFe82RGIcdlvxyaAPRuDuJhFjbh78BFsnCufJkarwEyKa0azHxccw5qegpcP9yaO0FKoohanxgiAfK1Lqwba51bKtjacbvdjMmcBkiv8kd62sBd98c4twa98sgj3iPh7nkP4
rlaejTPrua1DhBdg0jrIoDBi8fc1GIJAigivIGaxs1OmfPcctNadK3HErvzPLCeDPD8fkMNPCBcIwuoGfEHegOfk9k9pwktslqaBenaati1uNthMiyk9ndpy7gdIz88iot6A09cbNeIMheyjBvbeegL7aGp7mCb91hCxnvgV5abfImrPfLbrbraAsN6loJgh

Les deux chaînes de hachage bb66000000000000d698000000000000

Tout comme "C, 128 octets - par: squeamish ossifrage", les bits d'ordre supérieur n'influencent jamais les bits d'ordre inférieur, cela peut être exploité.

Code

Visual C ++, utilise des opérations de chaîne « non sécurisées »

#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>

long long x, y;

//Original hash function (not used for cracking).
void h(char inp[]){
    long long c;
    int index = 0;
    int len = strlen(inp);
    x = 0;
    y = 0;
    long long p = 0;
    for (c = 9; c ; c = (index<len?inp[index++]:-1) + 1) {
        for (++p; c--;) {
            x = x*'[3QQ' + p;
            y ^= c*x;
            y ^= x ^= y;
        }
    }
    printf("%016llx%016llx\n", x, y);
}

//Partial hash, takes a string and a starting point in the stream.
//The byte 0x08 must be prepended to a string in order to produce a full legal hash.
void hp(char inp[],long long p){
    long long c;
    int index = 0;
    int len = strlen(inp);
    x = 0;
    y = 0;
    for (index = 0; index<len; index++) {
        c = inp[index] + 1;
        for (++p; c--;) {
            x = x*'[3QQ' + p;
            y ^= c*x;
            y ^= x ^= y;
        }
    }
}

//Reverse partial hash, backtracks the inner state.
void hprev(char inp[], long long p){
    long long c;
    long long clim;
    int index = 0;
    int len = strlen(inp);
    p += len + 1;
    x = 0;
    y = 0;
    for (index = len-1; index>=0; index--) {
        clim = inp[index] + 1;
        c = 0;
        for (--p; c<clim;c++) {
            y ^= x;
            x ^= y;
            y ^= c*x;
            x -= p;
            x = x * 17372755581419296689;
            //The multiplicative inverse of 1530089809 mod 2^64.
        }
    }
}
const int rows = 163840;
const int maprows = 524288;

//Store for intermediate input strings, row 0 contains 64 columns with 3-char strings,
//row 1 contain 32 columns with 6-char strings and so forth, the final strings will
//contain one string from each column, in order.
char store[7][rows][512];

//Storage for a hashmap, used for matching n strings with n string in O(n) time.
char map[maprows][512];

int _tmain(int argc, _TCHAR* argv[])
{
    char alpha[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int row;
    int col;
    int layer;
    int a=0, b=0, c=0;
    int colzero;
    //Produce some starting strings.
    for (row = 0; row < rows; row++){
        //All column 0 strings begin with 0x08 in order to imitate the hash.
        store[0][row][0] = 8;
        colzero = 1;
        for (col = 0; col < 64; col++){
            store[0][row][col * 8 + colzero] = alpha[a];
            store[0][row][col * 8 + colzero + 1] = alpha[b];
            store[0][row][col * 8 + colzero + 2] = alpha[c];
            store[0][row][col * 8 + colzero + 3] = 0;
            colzero = 0;
        }
        a++;
        if (a >= 52){
            b++;
            a = 0;
            if (b >= 52){
                c++;
                b = 0;
            }
        }
    }
    //Layer for layer, column for column, build strings that preserve successively
    //more zero bits. Forward calculated partial hashes are matched with backwards
    //calculated partial hashes.
    for (layer = 1; layer < 7; layer++){
        int slayer = layer - 1;
        int swidth = 1 << (slayer + 3);
        int width = 1 << (layer + 3);
        int slen = 3 << slayer;
        int len = 3 << layer;
        int colnum;
        int layershift=slayer*8;
        for (col = 0,colnum=0; col < 512; col+=width,colnum++){
            printf("Layer: %i, column: %i\n",layer,colnum);
            memset(map, 0, sizeof map);
            int col2 = col + swidth;
            for (row = 0; row < rows; row++){
                hprev(store[slayer][row] + col2, 1 + slen*(1 + colnum * 2));
                x = (x >> layershift) & 255;
                y = (y >> layershift) & 255;
                int index = (x << 3) | (y << 11);
                for (a = 0; a < 8; a++){
                    if (map[index + a][0] == 0){
                        strcpy_s(map[index + a], store[slayer][row] + col2);
                        break;
                    }
                }
            }
            int destrow = 0;
            for (row = 0; row < rows && destrow < rows; row++){
                hp(store[slayer][row] + col, !!colnum + slen*(colnum * 2));
                x = (x >> layershift) & 255;
                y = (y >> layershift) & 255;
                int index = (x << 3) | (y << 11);
                for (a = 0; a < 8 && destrow < rows; a++){
                    if (map[index + a][0]){
                        strcpy(store[layer][destrow] + col, store[slayer][row] + col);
                        strcat(store[layer][destrow] + col, map[index + a]);
                        destrow++;
                    }
                }
            }
        }
    }
    memset(map, 0, sizeof map);
    char temp[1000];
    std::ofstream myfile;
    myfile.open("hashout.txt");
    for (row = 0; row < rows; row++){
        hp(store[6][row], 0);
        sprintf(temp, "%016llx%016llx", x, y);
        myfile << store[6][row] <<" " << temp << "\n";
    }
    myfile << "\n";
    //The final hash set has 96 of 128 output bits set to 0, I could have gone all
    //the way, but this is enough to find a collision via the birthday paradox.
    for (row = 0; row < rows; row++){
        hp(store[6][row], 0);
        long long xc = x;
        long long yc = y;
        int pos = (xc >> 45 | ((yc >> 48) & 7)) & (maprows-1);
        while (map[pos][0]!=0){
            hp(map[pos], 0);
            if (x == xc && y == yc){
                myfile << store[6][row] << "\n" << map[pos] << "\n";
                sprintf(temp,"%016llx%016llx", x, y);
                myfile << temp << "\n\n";
            }
            pos = (pos + 1) % maprows;
        }
        strcpy_s(map[pos], store[6][row]);
    }
    myfile.close();
    printf("done");
    getchar();
    return 0;
}
aaaaaaaaaaaa
la source
Impressionnant! Je suis en fait flatté d'une manière étrange! : D
M. Llama
De plus, pour ma propre éducation personnelle, quand vous dites que les bits d'ordre supérieur n'affectent jamais les bits inférieurs, que voulez-vous dire? Les bits d'ordre supérieur de la chaîne d'entrée ou de l'état de hachage?
M. Llama
@ Mr.Llama Dans l'état de hachage, les bits supérieurs de x et y n'influenceront jamais les bits inférieurs, donc par exemple si vous basculez sur les bits du milieu pendant le calcul, la partie inférieure du hachage sortira toujours à droite. Cela me permet de commencer par ignorer tout sauf les bits les plus bas de l'état de hachage, puis lorsque je les ai sous contrôle complet, je passe à la couche de bits suivante, et ainsi de suite.
aaaaaaaaaaaa
Cool! Merci pour l'explication!
M. Llama
Félicitations pour avoir remporté le défi des voleurs!
Dennis
12

Python, 109 octets par Sp3000

Notez que Martin a craqué en premier, donc je ne sais pas si cela mérite des points. D'un autre côté, j'ai fait une attaque de pré-image plutôt qu'une simple collision - un résultat beaucoup plus fort. Cela signifie que vous pouvez lui donner une valeur de hachage arbitraire, et il va construire une entrée qui génère cette valeur de hachage.

M = 2**128

# The hash to crack.
def jenkins(n):
    h = 42
    while n:
        h += n & (M - 1)
        n >>= 128
        h *= 1025
        h ^= h >> 6
        h %= M

    h *= 9
    h ^= h >> 11
    h *= 32769

    return h % M

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 Exception('modular inverse does not exist')
    else:
        return x % m

def invxorshift(h, s):
    r = h >> s
    while r:
        h ^= r
        r >>= s
    return h

def moddiv(a, b):
    return (a * modinv(b, M)) % M

def jenkins_crack(h):
    h = moddiv(h, 32769)
    h = invxorshift(h, 11)
    h = moddiv(h, 9)
    h = invxorshift(h, 6)
    h = moddiv(h, 1025)
    h -= 42
    return h

Et pour montrer que ça marche:

>>> from crack import *
>>> n = 2**128 + 1337
>>> h = jenkins(n)
>>> n2 = jenkins_crack(h)
>>> h2 = jenkins(n2)
>>> n != n2
True
>>> h == h2
True

Et pour donner un ensemble particulier de nombres qui entrent en collision:

N: 2**128
M: 43617
orlp
la source
3
Ma proposition initiale dans le bac à sable a accordé des points pour les attaques de collision, de pré-image et (choses légèrement simplificatrices) d'extension de longueur, mais j'ai décidé de garder le score simple. Lorsque j'ai édité ces parties, le fait que chaque soumission ne peut être piratée qu'une seule fois (c'est ainsi que fonctionnent généralement les flics et les voleurs) s'est en quelque sorte perdu. Voir votre réponse me fait regretter d'avoir gardé des attaques pré-image ...
Dennis
9

Python, 109 octets par Sp3000

340282366920938463463374607431768211414

et

113982837842983129870077688367927159293402923522160868689804433865221255200726

les deux donnent

132946164914354994014709093261515948032

L'algorithme divise l'entrée en blocs de 128 bits et modifie à plusieurs reprises le hachage (prédéfini 42) avec chaque bloc, avant de faire un hachage supplémentaire à la fin. Pour trouver une collision, notre objectif est de trouver deux nombres qui donnent le même résultat après avoir exécuté le pseudo-code suivant sur chaque bloc:

hash += chunk
hash += (hash << 10)
hash ^= (hash >> 6)
hash %= 2**128

Puisque le hachage est pris en mod 2 128, nous voulons rechercher des nombres qui décalent toutes les choses intéressantes en dehors de cette plage de bits. Mais le hachage est amorcé de 42sorte qu'il ait des bits non significatifs définis pour commencer:

000000000000000000000000 ... 000000000000000000101010

Mon idée était de me débarrasser de ces bits lors de l'ajout du premier morceau. Essayons donc 2 128 -42:

           000000000000000000000000 ... 000000000000000000101010     hash = 42
           111111111111111111111111 ... 111111111111111111010110     chunk = 2**128 - 42
          1000000000000000000000000 ... 000000000000000000000000     hash += chunk
10000000001000000000000000000000000 ... 000000000000000000000000     hash += hash << 10
10000010001000001000000000000000000 ... 000000000000000000000000     hash ^= hash >> 6
           000001000000000000000000 ... 000000000000000000000000     hash %= 2**128

C'est assez simple, essayons donc de l'utiliser comme l'un des deux nombres. (En effet, le premier numéro de la collision que j'ai utilisé est 2128 -42.

Maintenant, comment trouver un autre nombre avec le même résultat? Eh bien, après une itération, le hachage n'est 42plus, mais 2**122comme nous venons de le montrer. Maintenant, en ajoutant un deuxième morceau à notre numéro d'entrée, nous pouvons exécuter une autre itération. Nous pouvons choisir le deuxième morceau par le même argument que celui-ci, c'est-à-dire que nous voulons 2 128 -2 122 . Ensuite, le résultat intermédiaire après hash += chunksera identique et nous nous retrouverons avec le même résultat à la fin.

Nous pouvons donc calculer les deux nombres de la collision:

>>> 2**128-42
340282366920938463463374607431768211414L
>>> 2**128-42 + ((2**128-2**122)<<128)
113982837842983129870077688367927159293402923522160868689804433865221255200726L

Nous pouvons facilement générer beaucoup plus de collisions comme celle-ci.

Martin Ender
la source
Je craquais aussi cela - presque terminé. Est-ce un pistolet le plus rapide dans le concours ouest ou puis-je encore obtenir des points pour l'avoir affiché?
orlp
@orlp Normalement, seul le premier voleur obtient un point. Sinon, les gens pourraient simplement générer des millions de fissures supplémentaires une fois la première fissure publiée.
Martin Ender
1
Lame = / Je pense que je vais arrêter de relever ce défi. Je n'aime pas courir contre les autres - je veux juste énigmer. Ne peut-il y avoir une fenêtre de temps pour les fissures après la première, avec seulement 1 fissure par personne?
orlp
@orlp La version originale dans le bac à sable avait trois méthodes différentes pour casser un flic, et toutes les trois pouvaient être publiées indépendamment. Je suppose que c'est un modèle intéressant à étudier à un moment donné. Mais jusqu'à présent, dans les CnR précédents, autoriser plusieurs fissures aurait toujours plus brisé le défi qu'il ne l'aurait amélioré.
Martin Ender
1
Voir ma réponse pour une attaque de pré-image, plutôt qu'une collision :)
orlp
8

Mathematica, 89 octets par LegionMammal978

0

et

16

Les deux cèdent 0.

Le principe de ce flic est de faire évoluer un automate cellulaire 1-D binaire "aléatoire" à partir d'une condition initiale "aléatoire" pour un nombre "aléatoire" d'étapes, puis d'interpréter les 128 premières cellules du résultat comme un entier.

Le problème est que la règle est déterminée simplement par Mod[#^2,256], de sorte que tout multiple de 16 donne la règle 0, qui est la règle triviale où toutes les cellules sont toujours nulles. Si l'entrée n'est pas divisible par 99 alors nous évoluerons au moins 1 pas, donc la sortie est toujours nulle. Donc, deux multiples qui ne sont pas des multiples de 99 entrent définitivement en collision. Cependant, l'entrée donne 0 également 0 (bien qu'elle n'utilise jamais la règle), car la condition initiale n'est que la représentation binaire de l'entrée (qui est entièrement composée de zéros dans ce cas).

Soit dit en passant, nous pouvons trouver d'autres collisions qui sont complètement indépendantes de la règle. Comme indiqué ci-dessus, tout multiple de 99 signifie que l'automate cellulaire n'est pas du tout évolué, donc le résultat est simplement les 128 premiers bits (les plus significatifs) de la condition initiale ... qui n'est lui-même que le numéro d'entrée. Donc, si nous prenons deux multiples qui ne diffèrent pas dans les 128 premiers bits (remplis à droite avec des zéros), nous obtenons également une collision. L'exemple est simple M = 99, N = 99*2 = 198.

Martin Ender
la source
8

J, 39 octets

Le premier chiffre est:

10000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000

Autrement dit, 10000000répété 64 fois. Le deuxième nombre est celui plus un, c'est-à-dire

10000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000001

Les deux donnent

322124197561777885386414076216564234267

Explication

Commençons par x := H 10000000 = 146018215378200688979555343618839610915, et y := 2^128. Plutôt que de trouver a, btel a == b mod y, nous chercherons a, btel x^a == x^b mod y, en utilisant les tours de puissance dans l'algorithme.

Mais il doit y en avoir de ktels qui x^k == 1 mod y, depuis le x, ycoprime, et pour cela knous devons en avoir a == b mod k. Nous pouvons donc trouver le logarithme discret de 1 mod y, et pour la première étape, nous obtenons

x ^ (k = 85070591730234615865843651857942052864) == 1 mod 2^128

Alors maintenant, nous voulons trouver deux nombres a, btels que a == b mod k. Pour ce faire, nous avons mis en yêtre ket essayer de trouver a, bce que à x^a == x^b mod ynouveau. En utilisant la même logique, nous reprenons le logarithme discret et obtenons

x ^ (k = 21267647932558653966460912964485513216) == 1 mod 85070591730234615865843651857942052864

Nous répétons cela jusqu'à ce que nous arrivions à un petit y, auquel cas il est trivial de trouver deux nombres qui hachent la même chose modulo y. Après 63 itérations y = 4, moment auquel pratiquement deux nombres fonctionnent.

Voici le code Mathematica pour générer la chaîne de journaux discrète:

k = 0; x = 146018215378200688979555343618839610915; y = 2^128; While[y > 10, y = MultiplicativeOrder[x, y]; k++; Print[k, " ", y]];

Cela donne la sortie suivante .

Sp3000
la source
La version légèrement plus courte est que si les premières centaines de chiffres sont les mêmes, il est improbable que le reste de l'entrée soit important. En fait, faire des maths pour briser cela est exagéré.
aaaaaaaaaaaa
@eBusiness C'est vrai. Il s'est avéré que cela n'avait pas beaucoup d'importance ici, mais au départ, j'étais inquiet de dépasser la 2^(2^30)limite, d'où le chèque.
Sp3000
En fait, je soupçonne qu'il pourrait être impossible de fabriquer une chaîne là où quelque chose au-delà du 512e chiffre compte. Vous avez réussi à produire le pire des scénarios. La fissure la plus simple doit être de tirer parti des zéros de tête internes: "100000001" "1000000001".
aaaaaaaaaaaa
7

Pyth, 8 octets par FryAmTheEggman

99999999999999999999999999

et

99999999999999999999999998

La précision en virgule flottante n'est pas suffisante pour cela.

Sp3000
la source
En fait, j'obtiens des résultats différents pour cela, mais je crois que cette stratégie fonctionnerait de toute façon, donc je vais la marquer comme fêlée. Travail rapide: P
FryAmTheEggman
Hmm bizarre. Je reçois 437409784163148pour les deux. Je me demande pourquoi il y a une différence ...
Sp3000
Vous utilisez probablement python 3.5 non? Je n'ai pas encore mis à jour, toujours sur 3.4 peut-être que c'est ça?
FryAmTheEggman
@FryAmTheEggman J'utilise l'interprète en ligne, en fait ...
Sp3000
En fait, oui, je comprends 437409784163148et 37409784163148je suppose que c'est juste perdu le dernier chiffre pour une raison quelconque, mais 99 ... 997 donne la même réponse que 999 ... 98.
FryAmTheEggman
6

CJam, 44 octets, utilisateur jimmy23013

Les chiffres sont trop gros pour être affichés, alors les voici sur Pastebin: num 1 , num 2 .

Le premier nombre est 600^2 = 360000un. Le deuxième numéro est le même, à l'exception des modifications suivantes:

Positions to change to "2": 605, 1811, 3001, 6603
Positions to change to "4": 1805, 3003, 57348, 208895
Positions to change to "5": 602, 1201, 2405, 3004
Positions to change to "6": 1203, 1802
Positions to change to "7": 12, 609, 5401, 7200
Positions to change to "8": 1, 2, 4, 6, 600, 1200, 1808, 2400, 3600, 4803

Les deux hachés 271088937720654725553339294593617693056.

Explication

Jetons un coup d'œil à la première moitié du code:

lW%                e#  Read input number as string, and reverse
600/               e#  Split every 600 digits, forming a 2D array
_z                 e#  Duplicate and zip, swapping rows and columns
{           }%     e#  For both arrays...
 JfbDb             e#  Find sum of S[i][j]*13^i*19^j, where S are the character values
                   e#  and the indices are from right to left, starting at 0.
      GK#          e#  Take modulo 16^20

         ...  ...  e#  (Rest of code irrelevant)

Donc, si nous pouvons trouver deux nombres d'entrée afin que les sommes de S[i][j]*13^i*19^jsoient le même modulo 16^20pour le tableau initial de 600 et le tableau zippé, alors nous avons terminé.

Pour rendre les choses un peu plus faciles, nous ne considérerons que 600^2 = 360000les nombres d'entrée à -digit, de sorte que le tableau de 600 de large ne soit que 600 par 600 carrés de chiffres. Cela rend les choses plus faciles à visualiser et est valable depuis 10^360000 ~ 2^(2^20.19) < 2^(2^30). Pour simplifier encore les choses, nous ne considérerons que ces chaînes d'entrée dont le carré des chiffres est symétrique le long de la diagonale principale, de sorte que le tableau d'origine et le tableau zippé sont les mêmes. Cela nous permet également d'ignorer l'inversion de chaîne initiale et la numérotation de droite à gauche, qui s'annulent mutuellement.

Pour commencer, nous pouvons considérer que le premier nombre est 360000un. Pour obtenir le deuxième nombre, nous voulons le modifier en changeant certains des chiffres afin que les sommes soient les mêmes modulo 16^20, tout en préservant la symétrie du carré des chiffres. Nous accomplissons cela en trouvant une liste de triplets (i, j, k)afin que

sum of k*(13^i 19^j + 19^i 13^j) == 0 mod 16^20

1 <= k <= 8est le montant pour augmenter le chiffre 1 (c.-à-d. passer à un chiffre de 2 à 9 - nous aurions pu inclure 0 mais nous n'en avions pas besoin) et 0 <= i < j < 600sont des paires d'index.

Une fois que nous avons les (i, j, k)triplés, nous changeons les chiffres à (i, j)et (j, i)pour 1+kobtenir le deuxième numéro. Les triplets ont été trouvés en utilisant un algorithme de retour en arrière gourmand, et pour le deuxième nombre au-dessus du carré de chiffres ressemble à:

188181811111711 ...
815112111711111 ...
851611111111111 ...
116114118112111 ...
811115111111111 ...
121451111111111 ...
811111111111111 ...
111111111111111 ...
111811111111111 ...
171111111111111 ...
111111111111111 ...
111211111111111 ...
711111111111111 ...
111111111111111 ...
111111111111111 ...

............... .
...............  .
...............   .

Par exemple, (i, j, k) = (0, 1, 7)correspond à la modification des chiffres (0, 1)(position 600*0 + 1 = 1) et (1, 0)(position 600*1 + 0 = 600) sur 1 + 7 = 8.


Voici le backtracker dans Python 3, bien qu'une inspection plus approfondie ait révélé que nous avons été assez chanceux, car aucun retour en arrière ne s'est réellement produit:

n = 16**20
L = [(k *(pow(13,i,n)*pow(19,j,n) + pow(19,i,n)*pow(13,j,n)) % n, i, j, k)
     for i in range(600) for j in range(600) for k in range(1, 9) if i < j]

L.sort(reverse=True)
stack = [(n, 0, [])]

while stack:
    k, index, result = stack.pop()

    if k == 0:
        print(result)
        break

    if index == len(L):
        continue

    stack.append((k, index+1, result)) # Don't include triplet

    if L[index][0] <= k:
        stack.append((k - L[index][0], index+1, result + [L[index][1:]])) # Include

Pour un bonus, voici un port moins efficace du hachage en Python 3. Il était inutile.

Sp3000
la source
5

PHP 4.1, 66 octets par Ismael Miguel

$ A=0111129112911291111111111111111111111111 php hash.php 2> /dev/null ; echo
0100038003800381129111111111111111111111
$ A=0111129112911291129111111111111111111111 php hash.php 2> /dev/null ; echo
0100038003800381129111111111111111111111
$ cat hash.php 
<? $a = getenv("A"); for($l=strlen($b.=$a*1);$i<40;$o.=+$b[+$i]^"$a"/$a,$i++);echo$o;

Trouvé à l'aide d'un hachage itéré simple, à partir de 1:

$ i=1; while true; do i=$(A=$i php hash.php  2> /dev/null); echo $i; done | head -n 10
0111111111111111111111111111111111111111
0100000000000001129111111111111111111111
0111129111111111111111111111111111111111
0100038000000001129111111111111111111111
0111129112911111111111111111111111111111
0100038003800001129111111111111111111111
0111129112911291111111111111111111111111
0100038003800381129111111111111111111111
0111129112911291129111111111111111111111
0100038003800381129111111111111111111111
Vi.
la source
Ouaip, celui-là est fissuré. Combien de temps at-il fallu pour y arriver?
Ismael Miguel
Le deuxième essai. Le premier essai consistait à rechercher les valeurs des 100 premiers hachages, le deuxième essai consistait à créer les chaînes de hachage (c. hash(hash(hash(...(hash(1)...)))-à-d.). La première chaîne a convergé en boucle presque instantanément. Je n'avais même pas besoin de sortir mon cracker de hachage multithread.
Vi.
Traduction: hachage assez faible?
Ismael Miguel
Oui.󠀠󠀠󠀠󠀠󠀠󠀠
Vi.
5

Python 3 (216) par Sp3000

Mes messages sont

5012053369354645637214643587103597313576086380250249302980438772005248488380915054746146050001036696049972235875591571028140916001206596142280971107479334216535925703480968283657357930602076844092875640359192729378384507238123245417656548512647301639542279794868512420586823155070914644206130805893968511673770843170450832829657206145931885656157628306896903719624729809643572222159364893644113710867223921580178741177106141068298067479650611992859787419779579962211254029169589775046869542029842374359998053713002047081002506346875804341770199884355810931652447801492691887376948615365487982834690942054717077615539311699691010938426302886867891090301248321702485904291177813145565144089044261424329155436660979948932491709511914065619715728353376578192548334780893602675684085757434059540582004872746967999949306946618036846307799677491651967418565531672392468089533111553281620101129322575737949904022139471688252420467041529301533363008476437812216585923822571793353317799365005036029476865
5012053369354645637214643587103103086948976188724715498910865650846170784131001427390927276355140411160919276493388206817700368694224128444524223814513348177926532982330730066315320819293979046126543806115318009892783577432467861426768883700930779409885418980853424256180864755881414774514084197887594253752179391098292488771920695965135791582218083012144604515253506370334133858904659263953147111654656123599460222236152128559750436960308887683690915261431659087040402402092795259541564130228515353133867041828417398395559815392177084002004583988047406317670433664624642858480970640416500369367395538257341309676777745698712896295462462064271676447460293684100001583256400774270688958051470568447233589146620275159126426142305307007744396679875427883384557759778766330566230012377845843842097372663092379922300568052486301863154557664156185573021849420011058607321977550938866119133331529852821217331665195832442542012455132139770813510559894254061471149750738447764616026512400623344132554752

J'ai utilisé ce code Python 2 pour les générer:

a,b = 14460445391122031029,16815296360833931837 #http://www.numberempire.com/numberfactorizer.php
pr = ~-a * ~-b

m0 = reduce(long.__or__, [long(b) << 26*i for i,b in enumerate(bin(pr)[2:])])
m1 = 1 << 26*i-1
m0 |= m1

#print m0, m1
print f(m0), f(m1)

Le grand module était un produit de deux nombres premiers aet b. Je suppose que l'espoir était qu'il serait impossible pour NP de prendre en compte le semi-temps, mais je suppose que 128 bits est trop petit car une page Web m'a donné la réponse tout de suite.

Le groupe multiplicatif modulo abaura l'ordre (a - 1) (b - 1) ce qui signifie que si nous élevons un nombre à cette puissance, il devra résulter en 0 ou (généralement) 1. Donc, je mets 1 bits à des endroits qui ont abouti à 2 (a-1) (b-1) étant multiplié dans le hachage. Ensuite, l'autre message est essentiellement 0, mais j'ai défini un autre bit dans chaque numéro pour que les longueurs soient identiques.

Je pense que cela aurait été plus ennuyeux si le hachage était au carré sur chaque bit, plutôt qu'après avoir utilisé tous les nombres premiers. Ensuite, il n'aurait pas été aussi simple de créer des exposants arbitraires pour eux.

feersum
la source
Beau travail :) Oui, la vulnérabilité que j'avais en tête était essentiellement que le semi-premier est visible dans le code, et j'ai réalisé que Mathematica pouvait le prendre en compte instantanément.
Sp3000
+1 Votre code est difficile à lire, mais sinon une belle et instructive fissure.
aaaaaaaaaaaa
5

C, 128 octets - par: squeamish ossifrage

Les deux chaînes suivantes hachent toutes les zéros:

dddl|lddH4|@dhxdxXdh0TXPdhhdx(dTxtlpdd@4Lhd|hdDpdhDdXLdXP4(PdddL|ldXdD(lddX4|0hddp4|ddP4Lxdp0dP@dhpTxPdhXdXxdhHDxHdllLttdhPT8pd(pT8Pdd0TL8dlLLTtddPtl8dP@DPPdhhDxhd804(pdh0Txpd@DDpLdhL4xtdXXdHXdd04lXht40dlddh4|@ddPTLXdhhDXHhtPH40dh0t8pd(pt80dhPtX0dhLtXtdhLT8thlLplTdhpt80dh0txpdhHDX(hdX8txdhhdxHdp|d@tdhlTx4dlptdxdh0T8PdT@t|Hdd@tL(ht(8DhdhHD8(hpHHP8dhLtXtdX8dhxdhpt8Pd@(D@Hdd@tLhdtxTLPdd0tlxhhL8X|dd8t|0dT04|Xddxt|phxxxhhdhpt8PhhxX8hdhlTX4dd4l||dd@TLHdXlTHtdhHd8hdX0THPdh(D8(d8xdh8dhp4xPd0HDp(dhl4xTdxlthtdhlTx4d8lT(TdhhdXHdphdP(dhp4x0d0Xd0XddTl||d88DH8dhhdxhdx|tHDdhLT8Thll0lTddPTlXdxXd(xdd0Tlxdhp480dhp4x0dd|LltdhPt80dtll|dddPTlXdxXd(xdd0Tlxdhp480dhp4x0dd|LltdhPt80dtll|dddP4Lxd|ptT8dhddxldH|4xDdhp4x0dDdl|LdhtD8|hhHx88ddpTL8hhphx@dhtd8|dphDP(dh0tx0hhDHx4dhpt8Pd@(D@HddLLLDhh|xxldhl4xTdhL4x4dhPt8Pd(HDx(dh(D8Hd4PT|8ddH4|@hh4H8ddhxd8XdDP4lxdhHd8hdl04d8ddXT|phdh8Thdd@TlHdhXdxxdllL44dD@4lHdhxdxXhd8XtxddLlLddT@T|(dhxdXXd|P44Xdhpt8pdlHDT0dhL4Xtd@ldpDdddl|LdXP4h0dhltXtdX8d(Xdh|tXdhhLXX|dhxd8XdP@D0PdhXDxXhtpHtPdd84|pddtl||dh(dx(d88Dh8ddx4|PhtT0DLdd@tL(hdX8Txdhp480d08d08dlll44d4dLLldhTdX|hh8Xxhdh048pd08d08ddPtL8d4H4l@dhhdxHd|pt4Xddp4lXhp(hPxdh|48DdxhDh(ddLlldd8XdH8dddl|LdLHDT0dhpt8pdlHDT0dh(d8hdTHtl@ddptl8dt84LPdh8dxxdlptD8dd04lxhhH8XxddDl|ldP|D@4ddTl||d|ptT8dh(dXhhd8X48dhPtXpd(8DxXdh@TX@dDP4L8dhpTX0d4@4|hdhHdxHdX8DHxdhPT8PhllplTdh0TXPhlXHLXddp4lXhtHXD(dhP4X0htH8dhdhLTx4hpxHPHdhhd8(dX8DHxdhpt80hhdHxTdlll44d@Hd@(dhhDxhdh0t8Pddh4|@ddh4|@dhptx0dpPD0@ddPtlxdhPT8pdhhdX(htTpDLdd@4L(dLHDtpdhxd8xdt84lPdlpTdxdDPTLXddLLLDdxlThtdlhd4PdXLTh4ddptLxd|@44(dhhd8HdtDLLlddxt|pd|hDd0ddPtLXhl@H|pdhDD8ld8dDhLdhXDXxdDxT|PdhHD8hdp8dpxdhp480d@XD@xddpTLXdHhD8(ddllLDdD|LL4dhpt80d@LdPDdh|4xDdP8dpXddLllddl8d4@dhptXpdd(4|@dhltx4d0Dd@LdhptxphdPHdpdhl4xTdxlthtdhHD8HdTdllldhLtX4dXP4(PdhLTxTd4X4LpddlllDdlpTD8dllltTdL(dtPdhDDxLdhLTx4dhptx0d|0T4Xdhl4xTdHL4XtdhpTXpdLp4dxddHt|@dHL484dhHDXHdHLtxtdhDdXldxL4H4dh|TxDhh8xX(dhLt8td8Lt(TdhHDx(d4DlLlddXT|PdHHD8(dlll44dlP4dxdd@tL(dL@4dhdd0tLxd4X4l0dhhdxhdDlLldddLLlddD04l8ddPtlxd(hd8hdd(T|@hdDp4|ddP4Lxdp0dP@dhptXpd(p4X0dhhd8(d8pT(0dh8d8Xhd(XT(dhddxLd@XD@8dd@tlhd@ld0ddhTD8|hhPH8@ddtl||dH0Tx0ddLlLddhp480dhHdxhd4lL|DdhXD8xdhhDX(dh048pd4Ll|ddddl|LdXP4h0dlll4thhdhxtddP4LXdhXdxXdhpTX0hdXXtxddlLLddx0Th0ddTl||hlhhlHdd|Ll4dHDdXldhhDX(hpxh0HdhDDXLdXDDhLdlhDTpht8Xdxdhpt8phhHXX8dd(t|@dHl4xtddp4LXhxhXH8dhDDxldDXt|PdhTDX|d|0ttxdhdDXLdDLLLddd84|PdT84LpdlhDTphl8hlxdhXD8xdHpt8Pdlhd40ddHT|@dhxdX8dhlT84dh|T8dhlXHLxdhxDxXdT4lL|dlllttd@xd@xdhhDXHhtXXD8dh(d8(d4p4|8dd04lxdxPThpdhHD8Hhdhx4hdhl4xthl|pLDdhltX4dhP4XPdd0Tlxdl@tDhddP4lXd0xD0xdhHD8Hd@8D@xdh0T8Pd0XDpxddPtl8dP@DPPdhhDxhd804(pdd04L8hpxHphdhDdxLdppD0@dd@tl(d88dHXdh0txpdXhDhHdd@Tlhdx8DHXdh0tXPdxxdH8dhPT8Pd484LPdlhD4pdxxdHxdd|Lltdhptx0dhlTx4hp8HPhdhPt8pdt4lL|ddtl||dH0Tx0dhxd8xhl@H|pddLllDhldP||dhdD8ldXLTHTdlhDTpddllLddd04lxhhH8Xxdh|48DdP8d0XddLLldd|@44hdhhd8hd4x4L0dhltXthh4H8Ddh4DX|dD@Tlhdh0tXpd8|T(ddhtDX|dlhdTPdd@tLhdThTl@dh8D8xdT(TL@dd@Tl(d8Hd(hdhXdxxhtHXdhdd0tl8d|HDDPdd8T|PdH04xPdd@Tl(d|@4t(dd(4|@dHp4xpdhpt80dh0txpdhp48phdXxTxdhhDXHhtPH40dh0t8pd(pt80dd8T|pdlxdt@dhp48PdD0TLXdh0t8Pd|lldTdh|t8DhphHp8

ddTl||d4|L|4dhptX0d4dllLddxT|pdxXdH8dlhDtPhlpH|@dd|Lltdhptx0dhlTx4hp8HPhdhPt8pdt4lL|ddtl||dH0Tx0ddLLLDd8tdH|dhDD8LdtxtLpdhxD8Xhd8xtxdhPt8Pd(8DX8dhddxLd0xd08dd0Tlxdxdd(Lddh4|@dXpt(Pdh048pd0xd0xdhhDX(d8p4Hpdh0480d(8DX8dhL4x4d4PT|XddPTLXdPDd@Ldddl|ld(P4X0ddDL|lht88DXdhPtxpd((Dx(dh0tx0dxXd(8dhpT8Pd0xD0XdlhD4pdT0T|8dh04XPht0H40dlhDtpdpHDP(dhlTXtdPHdpHdhXDxXhpPH0pddDl|lhltp|Ldh04x0dtXTL0ddLLLDdLhdtpdhL4xtdHDdXLddxt|0d4X4l0dh(Dxhdx04h0ddllLDd0PD0@dhXDxxhdx848dhDDxldpXDpXdhPt8pdhltxTdd04lxhhH8Xxdh|48DdP8d0XddLLldd|@44hdhhd8hd4x4L0dhltXthh4H8Ddh4DX|dD@Tlhdh0tXpd8|T(ddhtDX|dlhdTPdhlTXtdTX4L0dd@Tlhhh8xXHdhPt80d|XdD@dhp4xphd4Ptldd|LL4dL|ltDdhPTx0d80T(pdhpt8pd|pTtXdhpTX0hhth8Ddhxd8xdphdP(dh8D88dp(DPhdhHD8(htxXdXdh8dXXdXpTH0ddx4|PdpXDPxdhXDXXdxxdhXdhlt8Td@xD@8dhP4XPdhltX4dd@tlHdhXDxxdhPtXPd(8Dxxdh0t8PhdpHd0dh(D8HdX(D(Hdd@tLhht|@4Tdd@4lHdttll|dd0tlXhh|xxldd@TLHdlHdTPdd|LL4dt@T|hddx4|PdlHdtPddTl||d88DH8dlhdTpd40t|xddht|@dpPDP@dhHDxHhxthHDdhddxldxtDH|dhltx4d8Dd(ldd|LLthp0H0Pdhl4x4d|0T4Xdd|ll4dt8tLPdd@4lhd|0TTXddPtLXd(8d8xdhPTxPdHxd8xdhHDX(ddLllddhp48Pd0@d0PdhptxpdX(DhHdd0TlXhtPHTPddh4|@dTDlLldhDDxLhp(hPxdhdD8ldXLTHTddPtLXdTh4L@dhLtxTdlpTd8dhPtXpdhLtX4ddPTlXdxxdhXdhhd8(d404|8dhTd8|dhL4Xtddp4l8d4X4LpdhL4Xtd@ldpDdddl|LdXP4h0dhpTX0htXxDxdhpt8pddLlLddhp4XPhp0H00dh4Dx|dlp4D8dhPtxpd((Dx(dh0tx0dxXd(8dhDDxlhlL0ltdhhDxHd@|d0TdhHdxhdL0tD8dhhD8hhl|pLdddxt|pd|hDd0ddPtLXhl@H|pdhxDXxd8DdhldlhdtphpphppdhpT8PdH8dxXdlhd40dtXtlPdhTd8|dXlthtdhTDX|dx|4HDddxT|pdHDd8ldhL4X4dhP4XpdhtDx|ddXt|Pdh|T8DdHhdxhddLLLDhlxHl8dh0tXPd|(ddPddDL|LdHhdxhdhp4x0dl8dT@ddXT|phdh8Thdh(DXhd0HDP(dddl|lhd(xT(dhXdXxdTxtl0dd|lLtd8|4hddd4l||dXLTh4dd04lxdP8DP8ddxT|0dXXdh8ddP4lxd0@DpPdh8dXxddp4lxdhLt8tdHTdx|dh4Dx|dxLTHtdhhd8hd@DDpldd04LXdXlT(tdhXdXxdhPT8pdh(DXHdP@dp0ddP4LXdXpThPdllL4td((D8(dh0tXpd|(ddpdh(DxhhdL@DDdhHDx(dxL4(tdhLtXtdl@4dHdhxd8xdTh4L@dhXDXXhhdH8Tdd8T|PdH04xPdlllT4hllpLtdhhDXHhxxXhhdhXDxXdPDd@Ldd0TlXdHLtX4ddDL|ldXLT(4dhPtXPdXXd(8dhpt8phdH8thddxT|pd(ptXpddP4LxdLXDT@dhpT80dLptDxddxt|pdP@Dp0dhptx0d|0T4XdlpTdxdxpt(PdhHD8(d4TlL|dhHDx(d@hD@(dd@tl(d88dHXdh(Dx(d4pT|xddPtl8dP@DPPdhhDxhd804(pdhHD8Hhdhx4hddP4lxhdhXt(dhxdX8dp@DppdlllT4dP0dp@dddl|ldH8DXXdllLT4dPXdp8dd@tLHdlPTd8ddtL||d8PtHpddHt|@hd|@d4dh(dX(hdhXT(dhpT80hdHX4(dlpTdxdtDlLlddxT|pd(ptXpddP4LxdLXDT@dhpT80dLptDxddxt|pdP@Dp0dhptx0d|0T4XdlpTdxdxpt(PdhHD8(d4TlL|dhHDx(d@hD@(dddL|lhtph40dhpTxPdlp4dXdhDDxldpxD08dh(dX(dHlTxTdd|ll4d40t|Xdh0480ht@hT@dhptXphdHxT(dh(D8Hd4PT|8dhpt8pd88dhXddDl|LhxdHHtddPtlXd|pt4Xdd0Tl8d0(D0hdhhd8hdppd0@ddPTlXd8P4hpdhlTx4d8dDhLdd@TLhhllplTddXT|0dH|4XDdh|4xDht8XD8ddptl8dH8d88dd|LLTdh(DXhddHt|@hpXhp(dhdDxLdDhT|@dhP4X0dXhDHhdh0T8Pd((dxhdhhDx(hdx8Txddp4LXd8xDH8dhPTXpdlPtD8dh(DxHd@8D@Xdhl48Td00Dp@dhLT8Tdp(d0(dhhd8(d404|8dhhdx(dx0T(pdd|lL4ddXt|Pdd0TlXhxdH(4ddllLDhhLXX|dhXDx8hl8hLxdhpT80dLPtDXdhptX0dPXd0XddP4lxd0@DpPdlptd8dl(dTPdhxDx8d(ptX0dhpT80htxxdXdhhDxhdXltHtddh4|@d@|dPTdhdDXLhpph0Pdhp48Pdt4lL|dh04xpdLpTD8dd@4lhdl8dt@ddhT|@dPxDp8dd04lXd40t|xdd0TLxdTdlLLddpTLXd|pTT8dd04lxhhH8XxdhddxlhddPT|dd04LXdlhd4pdh8d8xhh|8XLdhxd8xd(8d8xdhp48pd(8DX8dhhDXHd4dllLddx4|0d8PTH0ddPtlxd|P44XdlpTdxd(XDXXddpTlxdHltX4dhLTxtd|HDD0

La fonction de hachage est conçue de telle sorte que les bits d'ordre supérieur n'influencent jamais les bits d'ordre inférieur, donc je peux générer une collection de chaînes où tous les xbits d'ordre inférieur sont nuls, puis je peux essayer des combinaisons concaténées de ces chaînes pour en trouver où plus de les bits inférieurs sont nuls, etc. Je suis sûr qu'il y a plus de façons de casser cela, et aussi des façons qui produisent des chaînes beaucoup plus courtes, mais de cette façon j'ai évité de faire beaucoup de maths.

aaaaaaaaaaaa
la source
Impressionnant! Ils ont tous les deux haché 0x0000000a0000000a0000000a0000000asur mon système, mais c'est quand même assez étonnant. ( echo -ne '\x0a' |./hashdonne également le même résultat.)
r3mainer
1
@squeamishossifrage Vous avez un retour à la ligne rouge après chacune des chaînes, sans que ce soit des zéros simples.
aaaaaaaaaaaa
Oh oui, mon erreur :-)
r3mainer
4

Python 3, 118 octets

int(H("9"+"0"*400))

et

int(H("9"+"0"*4000))

(c'est-à-dire: 9E400 et 9E4000)

Les deux produisent

83909358607540647658718900164058931893

En creusant un peu plus profondément, il semble que tout entier suivi de k chiffres répétés tels que k> 128 et (k% 4 == 0) renverra le même hachage. Par exemple, H("1"+"1"*32*4)et H("1"+"1"*33*4)sont les deux 13493430891393332689861502800964084413. Hmmm, 128 ...

tucuxi
la source
4

Python 2, 161 octets, par Puzzled

340282366920938463463374607431768211456 (decimal)
100000000000000000000000000000000 (hexadecimal)

et

340282366920938468780317283222139437056 (decimal)
100000000000001203B66F94300000000 (hexadecimal)

Les deux ont la sortie:

83F172CC3D050D131F64FD04B8181DC2

Les nombres sont 2 ^ 128 et 2 ^ 128 + (3 * 5 * 7 * 11 * 13 * 17) ^ 2 * 19 * 2 ^ 32.

jimmy23013
la source
3

Java, 299 octets par SuperJedi224

Pastebin pour M. En binaire, Ma 65535 1s, suivi de 2 0s.

Pastebin pour N. En binaire, Na 218451 s, suivi de 174766 0s.

Les deux donnent 0.

Notez que la base de l'algorithme est i.bitCount()*i.bitLength()+1et finalement, nous prenons le résultat à la puissance de iet le prenons mod 2 128 . L'idée était donc simplement d'en trouver deux idivisibles par quatre, mais où la première expression donne 2 32 . Cela a été facilement fait en factorisant 2 32 -1 et en choisissant deux facteurs pour le nombre de 1 et la largeur totale des bits du nombre.

Edit: En fait, il y a un peu plus de raisons pour lesquelles Mdonne zéro, mais nous pouvons facilement trouver plus de nombres qui donnent zéro à cause de mon explication en utilisant d'autres facteurs de 2 32 -1 de sorte qu'il y ait au moins 64 zéros à la fin.

Martin Ender
la source
3

C, 134 octets (par Barteks2x)

10

et

20

hachage à la fois

0xa609779942cb9ef1

car l'algorithme hache uniquement le dernier chiffre!

r3mainer
la source
C'était une erreur stupide ...
barteks2x
3

C, 87 octets

$ echo B075343F9832CD60 | ./hash6_ ; echo
fc2e9f02bd284bd1
$ echo 5914BD1B71164C77 | ./hash6_ ; echo
fc2e9f02bd284bd1

Trouvé en utilisant mon collisionforcer de collision.

Vi.
la source
C'est peut-être dû au fait d'être uniquement 64 bits.
Vi.
Bravo :-) Combien de temps at-il fallu?
r3mainer
Environ 7 minutes d'exécution du programme. Maintenant recommencé avec des mesures.
Vi.
1
Trouvé une autre collision: 473E0B6ED5AF2B92 7EC2BC9B5E9F5645 -> 0000000000000000 0EAC34C8A9F94389après 3525078917 appels de fonction de hachage et real 14m24.970s user 48m42.410sheure.
Vi.
3

Python 2, 115 octets, par squeamish ossifrage

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222

et

2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

La valeur de hachage n'a rien à voir avec l'ordre des blocs.

jimmy23013
la source
2

C ++, 239 octets par SpelingMistake

En utilisant le programme "principal" fourni, les deux entrées suivantes produisent le même hachage:

echo -n "dog" | ./h
481c27f26cba06cf

et

echo -n "fog" | ./h
481c27f26cba06cf

Les 8 premiers octets d'entrée ne sont jamais traités , en raison de ce bogue dans le code:

 for(I i=n;--i;) // and then we use q[i] for this iteration

car est --iévalué à false quand i==1, q[0](les 8 premiers octets: Iest un int64). Remplacer la condition de boucle par for(I i=n;i--;)aurait résolu ce problème .

tucuxi
la source
On dirait que les 8 premiers octets d'entrée sont simplement ignorés.
Vi.
Semble comme un bogue dans le code; le correctif va suffixe au lieu de préfixe.
tucuxi
1
Il y a également des collisions sans bogue (voir les commentaires à la question d'origine).
Vi.
2

Ruby, 90 octets, par MegaTom

4271974071841820164790043412339104229205409044713305539894083215644439451561281100045924173873152

et

23495857395130010906345238767865073260629749745923180469417457686044416983587046050252582956302336

qui sont 2 et 11 suivis de 40 octets zéro. Ils ont donc tous les deux 41 octets. La valeur de hachage est ajoutée par la longueur d'entrée pour chaque octet, puis elle est inversée en décimal. Une longueur d'entrée se terminant par1 peut garantir que la valeur de hachage se terminera 0assez rapidement. Ensuite, l'inverser réduit la longueur de la valeur de hachage de 1.

Les deux ont la valeur de hachage 259.

jimmy23013
la source
2

C # - 393 octets - par: Logan Dam

70776e65642062792031333337206861786f72et les 70776e65642062792031333337206861786f7200deux hachent 18E1C8E645F1BBD1.

aaaaaaaaaaaa
la source
Cool! Pourriez-vous expliquer comment vous l'avez craqué? Et peut-être le "rembourrage défectueux"?
ldam
@LoganDam C'est tout ce code qui fait basculer l'entrée, vous finissez par traiter un multiple de 8 caractères, et si la longueur d'entrée n'est pas un multiple de 8, vous substituez des zéros. Si j'ajoute des zéros au bon endroit, ils remplacent simplement le rembourrage, qui était des zéros en premier lieu.
aaaaaaaaaaaa