Cryptographic hash golf (ladrones)


12

Este concurso ha terminado.

No quedan respuestas resquebrajables en el desafío de la policía.

Hilo complementario de Cryptographic hash golf

Como recordatorio, estas son las reglas para los ladrones del desafío principal:

Tarea

Grieta cualquiera de de los policías presentaciones mediante la publicación de la siguiente en los ladrones hilo: dos mensajes M y N en I de tal manera que H (M) = H (N) y M ≠ N .

Puntuación

Romper las presentaciones de cada policía te da un punto. El ladrón con más puntos gana.

En el caso de un empate, el ladrón atado que logró la sumisión más larga gana.

Reglas adicionales

  • Cada envío de policía solo se puede descifrar una vez.

  • Si un envío de policía se basa en un comportamiento definido o no definido por la implementación, solo tiene que encontrar una grieta que funcione (verificablemente) en su máquina.

  • Cada grieta pertenece a una respuesta separada en el hilo de los ladrones.

  • Publicar un intento de craqueo inválido le prohíbe romper ese envío en particular durante 30 minutos.

  • No puede descifrar su propia presentación.

Ejemplo

Python 2.7, 22 bytes por usuario8675309

1

y

18

Tabla de clasificación

  1. eBusiness: 3 grietas, 393 bytes
  2. Martin Büttner: 3 grietas, 299 bytes
  3. jimmy23013: 3 grietas, 161 bytes
  4. Sp3000: 3 grietas, 44 bytes
  5. tucuxi: 2 grietas, 239 bytes
  6. Vi .: 2 grietas, 87 bytes
  7. Feersum: 1 crack, 216 bytes
  8. Mathmandan: 1 crack, 139 bytes
  9. ossifrage aprensivo: 1 crack, 134 bytes

Respuestas:


5

C, 122 bytes - por: Sr. Llama

bmaj8PCosFLAJjeHaevvvchnJedmg2iujpePOPivI2x2asw0yKa2eA15xvFJMFe82RGIcdlvxyaAPRuDuJhFjbh78BFsnCufJkarwEyKa0azHxccw5qegpcP9yaO0FKoohanxgiAfK1Lqwba51bKtjacbvdjMmcBkiv8kd62sBd98c4twa98sgj3iPh7nkP4
rlaejTPrua1DhBdg0jrIoDBi8fc1GIJAigivIGaxs1OmfPcctNadK3HErvzPLCeDPD8fkMNPCBcIwuoGfEHegOfk9k9pwktslqaBenaati1uNthMiyk9ndpy7gdIz88iot6A09cbNeIMheyjBvbeegL7aGp7mCb91hCxnvgV5abfImrPfLbrbraAsN6loJgh

Ambas cadenas se combinan para bb66000000000000d698000000000000

Al igual que "C, 128 bytes - por: apretar osteo", los bits de orden superior nunca influyen en los bits de orden inferior, esto puede explotarse.

Código

Visual C ++, utiliza operaciones de cadena " inseguras "

#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;
}

¡Increíble! De hecho, me siento halagado de una manera extraña. : D
Sr. Llama

Además, para mi propia educación personal, cuando dices que los bits de orden superior nunca afectan a los inferiores, ¿qué quieres decir? ¿Los bits de orden superior de la cadena de entrada o del estado hash?
Sr. Llama

@ Mr.Llama En el estado hash, los bits superiores de x e y nunca influirán en los bits inferiores, por ejemplo, si activa los bits intermedios durante el cálculo, la parte baja del hash seguirá saliendo bien. Esto me permite comenzar ignorando todo menos los bits más bajos del estado hash, luego, cuando los tengo bajo control completo, paso a la siguiente capa de bits, y así sucesivamente.
aaaaaaaaaaaa

¡Frio! ¡Gracias por la explicación!
Sr. Llama

¡Felicitaciones por ganar el desafío de los ladrones!
Dennis

12

Python, 109 bytes por Sp3000

Tenga en cuenta que Martin se rompió primero, así que no estoy seguro de si esto merece puntos. Por otro lado, hice un ataque de preimagen en lugar de una simple colisión, un resultado mucho más fuerte. Esto significa que puede darle un valor hash arbitrario, y construirá una entrada que genere ese valor hash.

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

Y para demostrar que funciona:

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

Y para dar un conjunto particular de números que colisionan:

N: 2**128
M: 43617

3
Mi propuesta inicial en la caja de arena otorgó puntos por colisión, preimagen y (algo demasiado simplificado) ataques de extensión de longitud, pero decidí mantener la puntuación simple. Cuando edité esas partes, el hecho de que cada presentación solo se puede descifrar una vez (que es como suele funcionar la policía y los ladrones) de alguna manera se perdió. Ver su respuesta me hace desear haber mantenido los ataques de preimagen ...
Dennis

9

Python, 109 bytes por Sp3000

340282366920938463463374607431768211414

y

113982837842983129870077688367927159293402923522160868689804433865221255200726

ambos rinden

132946164914354994014709093261515948032

El algoritmo divide la entrada en fragmentos de 128 bits y modifica repetidamente el hash (sembrado a 42) con cada fragmento, antes de realizar un hash adicional al final. Para encontrar una colisión, nuestro objetivo es encontrar dos números que den el mismo resultado después de ejecutar el siguiente pseudocódigo en cada fragmento:

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

Dado que el hash se toma mod 2 128 , queremos buscar números que cambien todas las cosas interesantes fuera de este rango de bits. Pero el hash está sembrado, por 42lo que tiene algunos bits no tan significativos establecidos para comenzar:

000000000000000000000000 ... 000000000000000000101010

Mi idea era deshacerme de esas partes al agregar el primer fragmento. Entonces intentemos 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

Eso es bastante simple, así que tratemos de usarlo como uno de los dos números. (De hecho, el primer número de la colisión que utilicé es 2 128 -42.

Ahora, ¿cómo encontramos otro número con el mismo resultado? Bueno, después de una iteración, el hash ya no está 42, pero 2**122como acabamos de mostrar. Ahora, agregando un segundo fragmento a nuestro número de entrada, podemos ejecutar otra iteración. Podemos elegir el segundo fragmento con el mismo argumento que este, es decir, queremos 2 128 -2 122 . Luego, el resultado intermedio después hash += chunkserá idéntico y terminaremos con el mismo resultado al final.

Entonces podemos calcular los dos números de la colisión:

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

Podemos generar fácilmente muchas más colisiones como esta.


También estaba resolviendo esto, casi listo. ¿Es este el arma más rápida en el concurso oeste o todavía puedo obtener puntos por publicarlo?
orlp

@orlp Normalmente, solo el primer ladrón obtiene un punto. De lo contrario, las personas podrían generar millones de grietas adicionales una vez que se haya publicado la primera grieta.
Martin Ender

1
Cojo = / Creo que dejaré de hacer este desafío entonces. No disfruto compitiendo contra otros, solo quiero enredar. ¿No puede haber una ventana de tiempo para las grietas después de la primera, con solo 1 grieta por persona?
orlp

@orlp La versión original en el sandbox tenía tres métodos diferentes para descifrar a un policía, y los tres podían publicarse de forma independiente. Supongo que es un modelo interesante para investigar en algún momento. Pero hasta ahora, en CnR anteriores, permitir múltiples grietas siempre habría superado el desafío más de lo que lo habría mejorado.
Martin Ender

1
Vea mi respuesta para un ataque previo a la imagen, en lugar de una colisión :)
orlp

8

Mathematica, 89 bytes por LegionMammal978

0

y

16

Ambos rinden 0.

El principio de este policía es desarrollar un autómata celular binario "aleatorio" a partir de una condición inicial "aleatoria" para un número "aleatorio" de pasos, y luego interpretar las primeras 128 celdas del resultado como un número entero.

El problema es que la regla se determina simplemente por Mod[#^2,256], de modo que cualquier múltiplo de 16 da la regla 0, que es la regla trivial donde todas las celdas son siempre cero. Si la entrada no es divisible por 99, evolucionaremos al menos 1 paso, por lo que la salida siempre es cero. Entonces, dos múltiplos que no son múltiplos de 99 definitivamente chocan. Sin embargo, la entrada 0 también da 0 (a pesar de no usar nunca la regla), porque la condición inicial es solo la representación binaria de la entrada (que es todo ceros en este caso).

Como comentario aparte, podemos encontrar otras colisiones que son completamente independientes de la regla. Como se señaló anteriormente, cualquier múltiplo de 99 significa que el autómata celular no ha evolucionado en absoluto, por lo que el resultado es simplemente los primeros 128 bits (más significativos) de la condición inicial ... que es solo el número de entrada. Entonces, si tomamos dos múltiplos que no difieren en los primeros 128 bits (rellenados a la derecha con ceros), también tenemos una colisión. El ejemplo más sencillo de esto es M = 99, N = 99*2 = 198.


8

J, 39 bytes

El primer número es:

10000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000

Es decir, 10000000repetido 64 veces. El segundo número es ese más uno, es decir

10000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000001

Ambos rinden

322124197561777885386414076216564234267

Explicación

Comencemos con x := H 10000000 = 146018215378200688979555343618839610915, y y := 2^128. En lugar de encontrar a, btal cosa a == b mod y, buscaremos a, btal cosa x^a == x^b mod y, haciendo uso de las torres de poder en el algoritmo.

Pero debe haber algo kasí x^k == 1 mod y, ya que x, yson coprimos, y para eso kdebemos tener a == b mod k. Entonces podemos encontrar el logaritmo discreto de 1 mod y, y para el primer paso obtenemos

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

Así que ahora queremos encontrar dos números a, btales que a == b mod k. Para hacer esto, establecemos yser ky tratamos de encontrar a, beso de x^a == x^b mod ynuevo. Usando la misma lógica, tomamos el logaritmo discreto nuevamente y obtenemos

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

Repetimos esto hasta llegar a un pequeño y, en cuyo punto es trivial encontrar dos números que tengan el mismo módulo y. Después de 63 iteraciones y = 4, en ese punto básicamente funcionan dos números.

Aquí está el código de Mathematica para generar la cadena de registro discreta:

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

Esto da el siguiente resultado .


La versión ligeramente más corta es que si los primeros cientos de dígitos son iguales, es improbable que el resto de la entrada importe de alguna manera. En realidad, hacer cálculos matemáticos para romper esto es una exageración.
aaaaaaaaaaaa

@eBusiness Eso es cierto. Resultó que no importaba mucho aquí, pero inicialmente estaba preocupado por superar el 2^(2^30)límite, de ahí el cheque.
Sp3000

En realidad, sospecho que podría ser imposible fabricar una cadena donde cualquier cosa más allá del dígito 512 importa. Te las arreglaste para producir el peor de los casos. El crack más fácil debe ser aprovechar los ceros iniciales internos: "100000001" "1000000001".
aaaaaaaaaaaa

7

Pyth, 8 bytes por FryAmTheEggman

99999999999999999999999999

y

99999999999999999999999998

La precisión de coma flotante no es lo suficientemente grande para esto.


De hecho, estoy obteniendo resultados diferentes para esto, pero creo que esta estrategia funcionaría de todos modos, así que lo marcaré como agrietado. Trabajo rápido: P
FryAmTheEggman

Hmm raro. Tengo 437409784163148para los dos. Me pregunto por qué hay una diferencia ...
Sp3000

Probablemente estés usando Python 3.5 ¿verdad? No he actualizado todavía, todavía en 3.4 ¿tal vez es eso?
FryAmTheEggman

@FryAmTheEggman Estoy usando el intérprete en línea, en realidad ...
Sp3000

En realidad, sí consigo 437409784163148y 37409784163148así que supongo que acaba de perder el último dígito, por alguna razón, pero ... 99 997 da la misma respuesta que 999 ... 98.
FryAmTheEggman

6

CJam, 44 bytes, usuario jimmy23013

Los números son demasiado grandes para publicar, así que aquí están en Pastebin: num 1 , num 2 .

El primer número son 600^2 = 360000unos. El segundo número es el mismo, excepto por los siguientes cambios:

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

Ambos hash a 271088937720654725553339294593617693056.

Explicación

Echemos un vistazo a la primera mitad del código:

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)

Entonces, si podemos encontrar dos números de entrada para que las sumas S[i][j]*13^i*19^jsean del mismo módulo 16^20tanto para la matriz inicial de 600 anchos como para la matriz comprimida, entonces hemos terminado.

Para facilitar un poco las cosas, consideraremos solo 600^2 = 360000números de entrada de dígitos, de modo que la matriz de 600 de ancho sea solo un cuadrado de 600 por 600 de dígitos. Esto hace que las cosas sean más fáciles de visualizar y es válido desde entonces 10^360000 ~ 2^(2^20.19) < 2^(2^30). Para simplificar aún más las cosas, solo consideraremos las cadenas de entrada cuyo cuadrado de dígitos es simétrico a lo largo de la diagonal principal, de modo que la matriz original y la matriz comprimida sean las mismas. Esto también nos permite ignorar la inversión inicial de la cadena y la numeración del índice de derecha a izquierda, que se cancelan mutuamente.

Para comenzar, podemos tomar el primer número como 360000unos. Para obtener el segundo número, queremos modificar esto cambiando algunos de los dígitos para que las sumas sean del mismo módulo 16^20, mientras se preserva la simetría del cuadrado del dígito. Logramos esto al encontrar una lista de triples (i, j, k)para que

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

donde 1 <= k <= 8es la cantidad para aumentar el dígito 1 (es decir, cambiar a un dígito de 2 a 9; podríamos haber incluido 0 pero no lo necesitamos) y 0 <= i < j < 600son pares de índices.

Una vez que tenemos los (i, j, k)trillizos, que cambiar los dígitos en (i, j)y (j, i)para 1+kconseguir el segundo número. Los trillizos se encontraron usando un algoritmo de retroceso codicioso, y para el segundo número sobre el cuadrado del dígito se ve así:

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

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

Por ejemplo, (i, j, k) = (0, 1, 7)corresponde a cambiar los dígitos (0, 1)(posición 600*0 + 1 = 1) y (1, 0)(posición 600*1 + 0 = 600) a 1 + 7 = 8.


Aquí está el backtracker en Python 3, aunque una inspección más cercana reveló que tuvimos bastante suerte, ya que en realidad no hubo retroceso:

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

Como beneficio adicional, aquí hay un puerto no tan eficiente del hash en Python 3. Era inútil.


5

PHP 4.1, 66 bytes por 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;

Encontrado usando hashing iterado simple, comenzando desde 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

Sí, ese está roto. ¿Cuánto tiempo tardó en llegar allí?
Ismael Miguel

El segundo intento. El primer intento fue buscar los valores de los primeros 100 hashes, el segundo intento fue hacer las cadenas de hash (es decir hash(hash(hash(...(hash(1)...)))). La primera cadena convergió en un bucle casi al instante. Ni siquiera necesité sacar mi cracker de hash multiproceso.
Vi.

Traducción: ¿hash bastante débil?
Ismael Miguel

Sí.
Vi.

5

Python 3 (216) por Sp3000

Mis mensajes son

5012053369354645637214643587103597313576086380250249302980438772005248488380915054746146050001036696049972235875591571028140916001206596142280971107479334216535925703480968283657357930602076844092875640359192729378384507238123245417656548512647301639542279794868512420586823155070914644206130805893968511673770843170450832829657206145931885656157628306896903719624729809643572222159364893644113710867223921580178741177106141068298067479650611992859787419779579962211254029169589775046869542029842374359998053713002047081002506346875804341770199884355810931652447801492691887376948615365487982834690942054717077615539311699691010938426302886867891090301248321702485904291177813145565144089044261424329155436660979948932491709511914065619715728353376578192548334780893602675684085757434059540582004872746967999949306946618036846307799677491651967418565531672392468089533111553281620101129322575737949904022139471688252420467041529301533363008476437812216585923822571793353317799365005036029476865
5012053369354645637214643587103103086948976188724715498910865650846170784131001427390927276355140411160919276493388206817700368694224128444524223814513348177926532982330730066315320819293979046126543806115318009892783577432467861426768883700930779409885418980853424256180864755881414774514084197887594253752179391098292488771920695965135791582218083012144604515253506370334133858904659263953147111654656123599460222236152128559750436960308887683690915261431659087040402402092795259541564130228515353133867041828417398395559815392177084002004583988047406317670433664624642858480970640416500369367395538257341309676777745698712896295462462064271676447460293684100001583256400774270688958051470568447233589146620275159126426142305307007744396679875427883384557759778766330566230012377845843842097372663092379922300568052486301863154557664156185573021849420011058607321977550938866119133331529852821217331665195832442542012455132139770813510559894254061471149750738447764616026512400623344132554752

Usé este código de Python 2 para generarlos:

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)

El gran módulo fue producto de dos primos ay b. Supongo que la esperanza era que sería NP-imposible para nosotros factorizar el semiprime, pero supongo que 128 bits es demasiado pequeño ya que alguna página web me dio la respuesta de inmediato.

El módulo del grupo multiplicativo abtendrá orden (a - 1) (b - 1), lo que significa que si elevamos cualquier número a esa potencia, tendrá que resultar en 0 o (generalmente) 1. Así que puse 1 bits en lugares que resultaron en 2 (a-1) (b-1) se multiplica en el hash. Entonces, el otro mensaje es básicamente 0, pero configuré otro bit en cada número para que las longitudes sean las mismas.

Creo que hubiera sido más molesto si el hash estuviera al cuadrado en cada bit, en lugar de solo después de usar todos los números primos. Entonces no habría sido tan simple construir exponentes arbitrarios para ellos.


Buen trabajo :) Sí, la vulnerabilidad que tenía en mente era básicamente que el semiprime es visible en el código, y me di cuenta de que Mathematica podía factorizarlo instantáneamente.
Sp3000

+1 Su código es difícil de leer, pero por lo demás es un buen crack instructivo.
aaaaaaaaaaaa

5

C, 128 bytes - por: apremiante ossifrage

Las siguientes dos cadenas tienen hash a todos los ceros:

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 función hash está construida para que los bits de orden superior nunca influyan en los bits de orden inferior, por lo tanto, puedo generar una colección de cadenas donde todos los xbits de orden inferior son cero, luego puedo intentar combinaciones concatenadas de estas cadenas para encontrar algo más los bits más bajos son cero, etc. Estoy bastante seguro de que hay más formas de romper esto, y también formas que producen cadenas significativamente más cortas, pero de esta manera evité hacer muchas matemáticas.


¡Increíble! Ambos tienen problemas 0x0000000a0000000a0000000a0000000acon mi sistema, pero eso sigue siendo bastante sorprendente. ( echo -ne '\x0a' |./hashtambién da el mismo resultado.)
r3mainer

1
@squeamishossifrage Tienes una nueva línea de colorete después de cada una de las cadenas, sin eso son ceros simples.
aaaaaaaaaaaa

Oh sí, mi error :-)
r3mainer

4

Python 3, 118 bytes

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

y

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

(es decir: 9E400 y 9E4000)

Ambos producen

83909358607540647658718900164058931893

Excavando un poco más profundo, parece que cualquier número entero seguido de k dígitos repetidos de tal manera que k> 128 y (k% 4 == 0) devolverá el mismo hash. Por ejemplo, H("1"+"1"*32*4)y H("1"+"1"*33*4)son ambos 13493430891393332689861502800964084413. Hmmm, 128 ...


4

Python 2, 161 bytes, por Puzzled

340282366920938463463374607431768211456 (decimal)
100000000000000000000000000000000 (hexadecimal)

y

340282366920938468780317283222139437056 (decimal)
100000000000001203B66F94300000000 (hexadecimal)

Ambos tienen la salida:

83F172CC3D050D131F64FD04B8181DC2

Los números son 2 ^ 128 y 2 ^ 128 + (3 * 5 * 7 * 11 * 13 * 17) ^ 2 * 19 * 2 ^ 32.


3

Java, 299 bytes por SuperJedi224

Pastebin para M. En binario, Mtiene 65535 1s, seguido de 2 0s.

Pastebin para N. En binario, Ntiene 21845 1s, seguido de 174766 0s.

Ambos rinden 0.

Tenga en cuenta que la base del algoritmo es i.bitCount()*i.bitLength()+1y, en última instancia, llevamos el resultado al poder de iy lo tomamos mod 2 128 . Entonces, la idea era encontrar dos ique sean divisibles por cuatro, pero donde la primera expresión dé 2 32 . Eso se hizo fácilmente factorizando 2 32 -1 y seleccionando dos factores para el recuento de 1s y el ancho total de bits del número.

Editar: En realidad, hay un poco más de por qué Mproduce cero, pero podemos encontrar fácilmente más números que producen cero debido a mi explicación utilizando otros factores de 2 32 -1, de modo que hay al menos 64 ceros al final.



3

C, 87 bytes

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

Encontrado usando mi colisión bruteforcer.


Tal vez sea solo por ser de 64 bits.
Vi.

Bien hecho :-) ¿Cuánto tiempo tardó?
r3mainer

Unos 7 minutos de ejecución del programa. Ahora comenzó de nuevo con medidas.
Vi.

1
Encontró otra colisión: 473E0B6ED5AF2B92 7EC2BC9B5E9F5645 -> 0000000000000000 0EAC34C8A9F94389después de 3525078917 llamadas de función hash y real 14m24.970s user 48m42.410shora.
Vi.

3

Python 2, 115 bytes, por ossifrage aprensivo

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222

y

2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

El valor hash no tuvo nada que ver con el orden de los bloques.



2

C ++, 239 bytes por SpelingMistake

Usando el programa "principal" proporcionado, las siguientes dos entradas producen el mismo hash:

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

y

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

Los primeros 8 bytes de entrada nunca se procesan , debido a este error en el código:

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

porque se --ievalúa como falso cuando i==1, q[0](los primeros 8 bytes: Ies an int64). Reemplazar la condición de bucle con for(I i=n;i--;)habría solucionado esto.


Parece que los primeros 8 bytes de entrada simplemente se ignoran.
Vi.

Parece un error en el código; la solución va sufijo en lugar de prefijo.
tucuxi

1
También hay colisiones sin errores (ver comentarios a la pregunta original).
Vi.

2

Ruby, 90 Bytes, por MegaTom

4271974071841820164790043412339104229205409044713305539894083215644439451561281100045924173873152

y

23495857395130010906345238767865073260629749745923180469417457686044416983587046050252582956302336

que son 2 y 11 seguidos de 40 bytes cero. Entonces ambos tienen 41 bytes. El valor hash se agrega por la longitud de entrada para cada byte, y luego se invierte en decimal. Una longitud de entrada que termina con 1puede asegurarse de que el valor hash termine con 0bastante rapidez. Luego, invertirlo reduce la longitud del valor hash en 1.

Ambos tienen el valor hash 259.


2

C # - 393 bytes - por: Presa Logan

70776e65642062792031333337206861786f72y 70776e65642062792031333337206861786f7200ambos hash a 18E1C8E645F1BBD1.


¡Frio! ¿Podría explicar cómo lo descifró? ¿Y tal vez el "relleno defectuoso"?
señora

@LoganDam Es todo ese código el que cambia la entrada, terminas procesando un múltiplo de 8 caracteres, y si la longitud de la entrada no es un múltiplo de 8, sustituyes ceros. Si agrego algunos ceros en el lugar correcto, simplemente toman el lugar del relleno, que fue ceros en primer lugar.
aaaaaaaaaaaa
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.