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;
}
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.
Et pour montrer que ça marche:
Et pour donner un ensemble particulier de nombres qui entrent en collision:
la source
Python, 109 octets par Sp3000
et
les deux donnent
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: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
42
sorte qu'il ait des bits non significatifs définis pour commencer:Mon idée était de me débarrasser de ces bits lors de l'ajout du premier morceau. Essayons donc 2 128 -42:
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
42
plus, mais2**122
comme 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èshash += chunk
sera identique et nous nous retrouverons avec le même résultat à la fin.Nous pouvons donc calculer les deux nombres de la collision:
Nous pouvons facilement générer beaucoup plus de collisions comme celle-ci.
la source
Mathematica, 89 octets par LegionMammal978
et
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ègle0
, 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 donne0
é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
.la source
J, 39 octets
Le premier chiffre est:
Autrement dit,
10000000
répété 64 fois. Le deuxième nombre est celui plus un, c'est-à-direLes deux donnent
Explication
Commençons par
x := H 10000000 = 146018215378200688979555343618839610915
, ety := 2^128
. Plutôt que de trouvera, b
tela == b mod y
, nous chercheronsa, b
telx^a == x^b mod y
, en utilisant les tours de puissance dans l'algorithme.Mais il doit y en avoir de
k
tels quix^k == 1 mod y
, depuis lex, y
coprime, et pour celak
nous devons en avoira == b mod k
. Nous pouvons donc trouver le logarithme discret de 1 mody
, et pour la première étape, nous obtenonsAlors maintenant, nous voulons trouver deux nombres
a, b
tels quea == b mod k
. Pour ce faire, nous avons mis eny
êtrek
et essayer de trouvera, b
ce que àx^a == x^b mod y
nouveau. En utilisant la même logique, nous reprenons le logarithme discret et obtenonsNous 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 moduloy
. Après 63 itérationsy = 4
, moment auquel pratiquement deux nombres fonctionnent.Voici le code Mathematica pour générer la chaîne de journaux discrète:
Cela donne la sortie suivante .
la source
2^(2^30)
limite, d'où le chèque.Pyth, 8 octets par FryAmTheEggman
et
La précision en virgule flottante n'est pas suffisante pour cela.
la source
437409784163148
pour les deux. Je me demande pourquoi il y a une différence ...437409784163148
et37409784163148
je 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.CJam, 44 octets,
utilisateurjimmy23013Les chiffres sont trop gros pour être affichés, alors les voici sur Pastebin: num 1 , num 2 .
Le premier nombre est
600^2 = 360000
un. Le deuxième numéro est le même, à l'exception des modifications suivantes:Les deux hachés
271088937720654725553339294593617693056
.Explication
Jetons un coup d'œil à la première moitié du code:
Donc, si nous pouvons trouver deux nombres d'entrée afin que les sommes de
S[i][j]*13^i*19^j
soient le même modulo16^20
pour 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 = 360000
les 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 depuis10^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
360000
un. Pour obtenir le deuxième nombre, nous voulons le modifier en changeant certains des chiffres afin que les sommes soient les mêmes modulo16^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 queoù
1 <= k <= 8
est 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) et0 <= i < j < 600
sont des paires d'index.Une fois que nous avons les
(i, j, k)
triplés, nous changeons les chiffres à(i, j)
et(j, i)
pour1+k
obtenir 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 à:Par exemple,
(i, j, k) = (0, 1, 7)
correspond à la modification des chiffres(0, 1)
(position600*0 + 1 = 1
) et(1, 0)
(position600*1 + 0 = 600
) sur1 + 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:
Pour un bonus, voici un port moins efficace du hachage en Python 3. Il était inutile.
la source
PHP 4.1, 66 octets par Ismael Miguel
Trouvé à l'aide d'un hachage itéré simple, à partir de 1:
la source
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.Python 3 (216) par Sp3000
Mes messages sont
J'ai utilisé ce code Python 2 pour les générer:
Le grand module était un produit de deux nombres premiers
a
etb
. 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
ab
aura 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.
la source
C, 128 octets - par: squeamish ossifrage
Les deux chaînes suivantes hachent toutes les zéros:
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
x
bits 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.la source
0x0000000a0000000a0000000a0000000a
sur mon système, mais c'est quand même assez étonnant. (echo -ne '\x0a' |./hash
donne également le même résultat.)Python 3, 118 octets
et
(c'est-à-dire: 9E400 et 9E4000)
Les deux produisent
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)
etH("1"+"1"*33*4)
sont les deux13493430891393332689861502800964084413
. Hmmm, 128 ...la source
Python 2, 161 octets, par Puzzled
et
Les deux ont la sortie:
Les nombres sont 2 ^ 128 et 2 ^ 128 + (3 * 5 * 7 * 11 * 13 * 17) ^ 2 * 19 * 2 ^ 32.
la source
Java, 299 octets par SuperJedi224
Pastebin pour
M
. En binaire,M
a 655351
s, suivi de 20
s.Pastebin pour
N
. En binaire,N
a 218451
s, suivi de 1747660
s.Les deux donnent
0
.Notez que la base de l'algorithme est
i.bitCount()*i.bitLength()+1
et finalement, nous prenons le résultat à la puissance dei
et le prenons mod 2 128 . L'idée était donc simplement d'en trouver deuxi
divisibles 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
M
donne 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.la source
C, 134 octets (par Barteks2x)
et
hachage à la fois
car l'algorithme hache uniquement le dernier chiffre!
la source
C, 87 octets
Trouvé en utilisant mon collisionforcer de collision.
la source
473E0B6ED5AF2B92 7EC2BC9B5E9F5645 -> 0000000000000000 0EAC34C8A9F94389
après 3525078917 appels de fonction de hachage etreal 14m24.970s user 48m42.410s
heure.Python 2, 115 octets, par squeamish ossifrage
et
La valeur de hachage n'a rien à voir avec l'ordre des blocs.
la source
Python 2.x, 139 octets par Puzzled
H(2)
et
H(128)
les deux reviennent
16645614427504350476847004633262883518
.la source
C ++, 239 octets par SpelingMistake
En utilisant le programme "principal" fourni, les deux entrées suivantes produisent le même hachage:
et
Les 8 premiers octets d'entrée ne sont jamais traités , en raison de ce bogue dans le code:
car est
--i
évalué à false quandi==1
,q[0]
(les 8 premiers octets:I
est unint64
). Remplacer la condition de boucle parfor(I i=n;i--;)
aurait résolu ce problème .la source
Ruby, 90 octets, par MegaTom
et
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 par
1
peut garantir que la valeur de hachage se terminera0
assez rapidement. Ensuite, l'inverser réduit la longueur de la valeur de hachage de 1.Les deux ont la valeur de hachage
259
.la source
C # - 393 octets - par: Logan Dam
70776e65642062792031333337206861786f72
et les70776e65642062792031333337206861786f7200
deux hachent18E1C8E645F1BBD1
.la source