Golf crypté

34

Ce concours est terminé.

En raison de la nature des défis posés par les flics , le défi des flics devient beaucoup plus facile lorsque l'intérêt pour le défi des voleurs associés a diminué. Par conséquent, même si vous pouvez toujours publier des fonctions de hachage, votre réponse ne sera ni acceptée ni intégrée au classement.

Ce défi est une recherche de la mise en œuvre la plus courte d'une fonction de hachage qui est une collision résistant , à savoir, il devrait être impossible de trouver deux messages différents avec le même hachage.

En tant que policier, vous essayez d’inventer et de mettre en oeuvre une fonction de hachage pour trouver le meilleur compromis entre la taille du code et la résistance aux collisions. Utilisez trop d'octets et un autre flic vous égrenera!

En tant que voleur, vous essayez de déjouer les tentatives des flics en craquant leurs fonctions, prouvant qu'elles ne conviennent pas. Cela les obligera à utiliser plus d'octets pour renforcer leurs algorithmes!

Défi Cops

Tâche

Implémentez une fonction de hachage cryptographique H: I -> O de votre choix, où I est l’ensemble des entiers non négatifs inférieur à 2 2 30 et O l’ensemble des entiers non négatifs inférieurs à 2 128 .

Vous pouvez implémenter H en tant que fonction réelle qui accepte et retourne un entier unique, une représentation sous forme de chaîne d'un entier ou d'un tableau d'entiers ou un programme complet qui lit à partir de STDIN et imprime vers STDOUT en base 10 ou 16.

Notation

  • H qu’il doit résister au défi des voleurs défini ci-dessous.

    Si un voleur triomphe de votre soumission dans les 168 heures qui suivent son envoi, elle est considérée comme fissurée .

  • La mise en œuvre de H devrait être aussi courte que possible. La soumission non fissurée la plus courte sera la gagnante du défi des flics.

Règles supplémentaires

  • Si vous implémentez H en tant que fonction, veuillez fournir un wrapper pour exécuter la fonction à partir d'un programme qui se comporte comme expliqué ci-dessus.

  • Veuillez fournir au moins trois vecteurs de test pour votre programme ou votre wrapper (exemples d'entrées et leurs sorties correspondantes).

  • H peut être votre nouveau design (préféré) ou un algorithme bien connu, à condition de le mettre en œuvre vous-même. Il est interdit d'utiliser une fonction de hachage, une fonction de compression, un chiffrement, un PRNG, etc.

    Toute fonctionnalité intégrée couramment utilisée pour implémenter des fonctions de hachage (par exemple, la conversion de base) constitue un jeu équitable.

  • Le résultat de votre programme ou fonction doit être déterministe.

  • Il devrait exister un compilateur / interprète gratuit (comme dans Beer) pouvant être exécuté sur une plate-forme x86 ou x64 ou à partir d'un navigateur Web.

  • Votre programme ou fonction doit être raisonnablement efficace et doit hacher tout message en I inférieur à 2 2 19 en moins d'une seconde.

    Pour les cas extrêmes, le temps (mural) pris sur ma machine (Intel Core i7-3770, 16 Go de RAM) sera déterminant.

  • Compte tenu de la nature de ce défi, il est interdit de modifier le code de votre réponse de quelque manière que ce soit, que cela modifie la sortie ou non.

    Si votre soumission a été fissurée (ou même si elle ne l’a pas été), vous pouvez poster une réponse supplémentaire.

    Si votre réponse est invalide (par exemple, si elle n'est pas conforme à la spécification d'E / S), veuillez la supprimer.

Exemple

Python 2.7, 22 octets

def H(M):
 return M%17

Wrapper

print H(int(input()))

Le défi des voleurs

Tâche

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

Notation

  • Craquer chaque soumission de flic vous rapporte un point. Le voleur avec le plus de points gagne.

    En cas d'égalité des voix, le voleur à égalité qui a soumis la plus longue soumission est déclaré vainqueur.

Règles supplémentaires

  • Chaque soumission de flic ne peut être craqué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 du voleur.

  • Publier une tentative de cracking non valide vous interdit de cracker cette soumission pendant 30 minutes.

  • Vous ne pouvez pas craquer votre propre soumission.

Exemple

Python 2.7, 22 octets par utilisateur8675309

1

et

18

Classement

Soumission sécurisée

  1. CJam, 21 octets par eBusiness
  2. C ++, 148 octets par tucuxi
  3. C ++, 233 (?) Octets par Vi.

Soumissions non fissurées

Vous pouvez utiliser cet extrait de pile pour obtenir une liste des réponses non encore résolues.

function g(p){$.getJSON('//api.stackexchange.com/2.2/questions/51068/answers?page='+p+'&pagesize=100&order=desc&sort=creation&site=codegolf&filter=!.Fjs-H6J36w0DtV5A_ZMzR7bRqt1e',function(s){s.items.map(function(a){var h=$('<div/>').html(a.body).children().first().text();if(!/cracked/i.test(h)&&(typeof a.comments=='undefined'||a.comments.filter(function(b){var c=$('<div/>').html(b.body);return /^cracked/i.test(c.text())||c.find('a').filter(function(){return /cracked/i.test($(this).text())}).length>0}).length==0)){var m=/^\s*((?:[^,(\s]|\s+[^-,(\s])+)\s*(?:[,(]|\s-).*?([0-9]+)/.exec(h);$('<tr/>').append($('<td/>').append($('<a/>').text(m?m[1]:h).attr('href',a.link)),$('<td class="score"/>').text(m?m[2]:'?'),$('<td/>').append($('<a/>').text(a.owner.display_name).attr('href',a.owner.link))).appendTo('#listcontent');}});if(s.length==100)g(p+1);});}g(1);
table th, table td {padding: 5px} th {text-align: left} .score {text-align: right} table a {display:block}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><table><tr><th>Language</th><th class="score">Length</th><th>User</th></tr><tbody id="listcontent"></tbody></table>

Dennis
la source
Si une fonction de hachage renvoie par erreur des nombres supérieurs à 2 ^ 128-1, cela invalide-t-il la soumission ou prendrions-nous simplement le résultat modulo 2 ^ 128?
Martin Ender
@ MartinBüttner: Oui, vous devez prendre le résultat modulo 2 ^ 128.
Dennis
1
@Scimonster Ne répond pas aux exigences (jusqu'à 2 ^ 30 bits d'entrée, 128 bits de sortie)
CodesInChaos
1
Les flics et les voleurs ne vont-ils pas généralement dans le sens inverse?
haneefmubarak
2
Peut-être pourrions-nous avoir une règle selon laquelle les soumissions doivent inclure des exemples de hachage, il est assez ennuyeux de devoir utiliser le langage de programmation choisi par les émetteurs afin de pouvoir comparer les résultats avec ceux de la mise en oeuvre.
aaaaaaaaaaaa

Réponses:

6

CJam, 21 octets

1q3*{i+_E_#*^26_#)%}/

Prend une chaîne d'octets en entrée.

En pseudocode:

hash = 1
3 times:
    for i in input:
        hash = hash + i
        hash = hash xor hash * 14^14
        hash = hash mod (26^26 + 1)
output hash

Exemple de hachage:

"" (chaîne vide) -> 1
"Test" -> 2607833638733409808360080023081587841
"test" -> 363640467424586895504738713637444713

C’est peut-être un peu simple, la plage de sortie n’est qu’un peu plus de 122 bits, le renforcement en triple itération est déjà un peu cassé car il fait exactement la même chose à chaque fois, donc une entrée qui passe à 1 dans le premier itération sera une pause complète. Mais c'est court, et il n'y a pas de plaisir à être trop en sécurité.

aaaaaaaaaaaa
la source
Existe-t-il une version C d'accompagnement, comme dans l'autre message de CJam?
Vi.
@Vi. Non, pas encore au moins. Je n'ai jamais touché à bigint en C, existe-t-il une bibliothèque standard pour cela?
aaaaaaaaaaaaa
GMP ?
Vi.
3
Ici: pastebin.com/SDzA3JK4
ossifrage
1
@ Agawa001 Vous confondez votre terminologie. C'est un algorithme de hachage de fonction éponge à trois passes. Un chiffrement de César est un algorithme de chiffrement spécifique sans état interne.
aaaaaaaaaaaa
7

Python, 109 octets [ fissuré , et encore ]

def f(n,h=42,m=2**128):
 while n:h+=n&~-m;n>>=128;h+=h<<10;h^=h>>6;h%=m
 h+=h<<3;h^=h>>11;h+=h<<15;return h%m

J'ai essayé d'implémenter Jenkins un à la fois telle quelle, la seule différence étant la valeur initiale et le nombre de bits.

Fait amusant: Apparemment, Perl a utilisé le hasch de Jenkins à un moment donné .

Wrapper

print(f(int(input())))

Exemples

>>> f(0)
12386682
>>> f(1)
13184902071
>>> f(2**128-1)
132946164914354994014709093274101144634
>>> f(2**128)
13002544814292
>>> f(2**128+1)
13337372262951
>>> f(2**(2**20))
290510273231835581372700072767153076167
Sp3000
la source
6

C ++, 148 octets

typedef __uint128_t U;U h(char*b,U n,U&o){U a=0x243f6a8885a308d,p=0x100000001b3;for(o=a;n--;)for(U i=27;--i;){o=(o<<i)|(o>>(128-i));o*=p;o^=b[n];}}

__uint128_t est une extension GCC et fonctionne comme prévu. Le hachage est basé sur l'itération FNV (j'ai emprunté leur nombre premier, bien que ce asoient les premiers chiffres de Pi en hex), avec une rotation semblable à sha1 au début de chaque itération. Compiler avec-O3 , hacher un fichier de 10 Mo prend moins de 2 secondes, il reste donc une marge pour augmenter les itérations dans la boucle intérieure - mais je me sens généreux aujourd'hui.

De-uglified (noms de variables modifiés, commentaires ajoutés, espaces et paire d'accolades) pour votre plus grand plaisir:

typedef __uint128_t U;
U h(char* input, U inputLength, U &output){
    U a=0x243f6a8885a308d,p=0x100000001b3;    
    for(output=a;inputLength--;) {   // initialize output, consume input
        for(U i=27;--i;) {                          // evil inner loop
            output = (output<<i)|(output>>(128-i)); // variable roll 
            output *= p;                            // FNV hash steps
            output ^= input[inputLength];        
        }
    }
    // computed hash now available in output
}

Les suggestions de golf sont les bienvenues (même si je ne parviens pas à améliorer le code basé sur elles).

edit: correction de fautes de frappe en code dé-uglifié (la version golfée reste inchangée).

tucuxi
la source
osemble être non initialisé. Où outputest déclaré? Ou peut o- être est-ce output?
Vi.
La même chose pour n. Avez-vous réellement vérifié le code "dé-uglifié" à exécuter?
Vi.
Commencé le bruteforcer ...
Vi.
Même la version à 3 tours n'est pas facile.
Vi.
@Vi. Version corrigée et corrigée - désolé de ne pas l'avoir vérifiée mieux. Je suis fier de cette boucle intérieure. U i=81;i-=3aurait pu être encore plus vil, sans coûts d’exécution considérables.
tucuxi
5

CJam, 44 octets [ fissuré ]

lW%600/_z]{JfbDbGK#%GC#[md\]}%z~Bb4G#%\+GC#b

L'entrée est en base 10.

CJam est lent. J'espère que ça marche en 1 seconde sur un ordinateur ...

Des explications

lW%600/            e# Reverse, and split into chunks with size 600.
_z                 e# Duplicate and swap the two dimensions.
]{                 e# For both versions or the array:
    JfbDb          e# Sum of S[i][j]*13^i*19^j, where S is the character values,
                   e# and the indices are from right to left, starting at 0.
    GK#%GC#[md\]   e# Get the last 32+48 bits.
}%
z~                 e# Say the results are A, B, C, D, where A and C are 32 bits.
Bb4G#%             e# E = the last 32 bits of A * 11 + C.
\+GC#b             e# Output E, B, D concatenated in binary.

Eh bien, les choses en deux dimensions semblaient être une faiblesse ... Elle était destinée à faire des calculs lents plus rapidement au début. Mais il ne peut pas fonctionner en une seconde, peu importe ce que je fais, alors j'ai finalement supprimé le code lent.

Cela devrait également être mieux si j'ai utilisé des bits binaires et des bases supérieures.

Version C

__uint128_t hash(unsigned char* s){
    __uint128_t a=0,b=0;
    __uint128_t ar=0;
    __uint128_t v[600];
    int l=0,j=strlen(s);
    memset(v,0,sizeof v);
    for(int i=0;i<j;i++){
        if(i%600)
            ar*=19;
        else{
            a=(a+ar)*13;
            ar=0;
        }
        if(i%600>l)
            l=i%600;
        v[i%600]=v[i%600]*19+s[j-i-1];
        ar+=s[j-i-1];
    }
    for(int i=0;i<=l;i++)
        b=b*13+v[i];
    a+=ar;
    return (((a>>48)*11+(b>>48))<<96)
        +((a&0xffffffffffffull)<<48)
        +(b&0xffffffffffffull);
}
jimmy23013
la source
Pourriez-vous s'il vous plaît ajouter une description? Tout le monde ne connaît pas CJam.
Orlp
@orlp Edited ...
jimmy23013
Cela prend 0,4 s sur mon ordinateur, donc c'est bien dans la plage autorisée.
Dennis
Qu'est-ce que A, B, C et ainsi de suite? Des matrices? Quelles dimensions? Peut-il être facilement implémenté en C?
Vi.
1
Craqué , je crois.
Sp3000
5

C ++, 182 caractères (+ environ 51 caractères de passe-passe)

h=0xC0CC3051F486B191;j=0x9A318B5A176B8125;char q=0;for(int i=0;i<l;++i){char w=buf[i];h+=((w<<27)*257);j^=(h+0x5233);h+=0xAA02129953CC12C3*(j>>32);j^=(w+0x134)*(q-0x16C552F34);q=w;}

Plaque de cuisson:

void hash(const unsigned char* buf, size_t len, unsigned long long *hash1, unsigned long long *hash2)
{
    unsigned long long &h=*hash1;
    unsigned long long &j=*hash2;
    size_t l = len;
    const unsigned char* b = buf;

    // code here
}

Programme exécutable avec une fonction de golf

#include <stdio.h>

// The next line is 227 characters long
int hash(char*b,int l,long long&h,long long&j){h=0xC0CC3051F486B191;j=0x9A318B5A176B8125;char q=0;for(int i=0;i<l;++i){char w=b[i];h+=((w<<27)*257);j^=(h+0x5233);h+=0xAA02129953CC12C3*(j>>32);j^=(w+0x134)*(q-0x16C552F34);q=w;}}

int main() {
    char buf[1024];
    int l  = fread(buf, 1, 1024, stdin);
    long long q, w;
    hash(buf, l, q, w);
    printf("%016llX%016llX\n", q, w);
}
Vi.
la source
2
Je pense que la déclaration de fonction, etc. compte pour le nombre de caractères.
Ypnypn
@Ypnypn, nombre de caractères comptés dans une déclaration de fonction vers le bas.
Vi.
Quel est le hash de sortie? Je suppose que c'est ((h << 64) | j).
tucuxi
Oui. Ou juste une paire de nombres 64 bits. J'ai découvert que __uint128_tseulement après avoir implémenté ceci.
Vi.
1
@Dennis, Fait.󠀠
Vi.
4

Pyth, 8 Cracked

sv_`.lhQ

Essayez-le en ligne

Une réponse un peu bête, je vais expliquer comment cela fonctionne car la plupart des gens ne peuvent pas lire Pyth. Cela prend le journal naturel de un plus l'entrée, puis le convertit en chaîne. Cette chaîne est inversée, puis évaluée et convertie en un entier.

Une traduction en python ressemblerait à ceci:

import math
n = eval(input()) + 1
rev = str(math.log(n))[::-1]
print(int(eval(rev)))
FryAmTheEggman
la source
Fissuré ?
Sp3000
4

Python 3, 216 octets [ fissuré ]

def f(m):
 h=1;p=[2]+[n for n in range(2,102)if 2**n%n==2];l=len(bin(m))-2;*b,=map(int,bin((l<<(l+25)//26*26)+m)[2:])
 while b:
  h*=h
  for P in p:
   if b:h=h*P**b.pop()%0xb6ee45a9012d1718f626305a971e6a21
 return h

En raison d'une incompatibilité avec les spécifications, je peux penser à au moins un léger vulnérabilité, mais à part cela, je pense que c'est au moins une preuve de force brute. J'ai vérifié les 10 premiers millions de hachages, entre autres choses.

En termes de golf, cela serait plus court en Python 2, mais j'ai sacrifié quelques octets pour plus d'efficacité (car cela ne va probablement pas gagner de toute façon).

Edit: C’était ma tentative de mettre en œuvre le hachage très lisse , mais malheureusement 128 bits était beaucoup trop petit.

Wrapper

print(f(int(input())))

Exemples

>>> f(0)
2
>>> f(123456789)
228513724611896947508835241717884330242
>>> f(2**(2**19)-1)
186113086034861070379984115740337348649
>>> f(2**(2**19))
1336078

Explication du code

def f(m):
 h=1                                             # Start hash at 1
 p=[2]+[n for n in range(2,102)if 2**n%n==2]     # p = primes from 2 to 101
 l=len(bin(m))-2                                 # l = bit-length of m (input)
 *b,=map(int,bin((l<<(l+25)//26*26)+m)[2:])      # Convert bits to list, padding to
                                                 # a multiple of 26 then adding the
                                                 # bit-length at the front

 while b:                                        # For each round
  h*=h                                           # Square the hash
  for P in p:                                    # For each prime in 2 ... 101
   if b:h=(h*P**b.pop()                          # Multiply by prime^bit, popping
                                                 # the bit from the back of the list
           %0xb6ee45a9012d1718f626305a971e6a21)  # Take mod large number

 return h                                        # Return hash

Un exemple de remplissage pour f(6):

[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]

(len 3)(------------------ 23 zeroes for padding -------------------------)(input 6)
       (---------------------------- length 26 total ------------------------------)
Sp3000
la source
Cracked
Feersum
4

C, 87 octets [ fissuré ]

C'est le programme complet. aucun emballage requis. Accepte les entrées binaires via stdin et génère un hachage hexadécimal sur stdout.

c;p;q;main(){while((c=getchar())+1)p=p*'foo+'+q+c,q=q*'bar/'+p;printf("%08x%08x",p,q);}

Cela ne fait que calculer un hachage 64 bits, alors je prends un peu de risque ici.

Au cas où quelqu'un se le demanderait, les deux constantes 'foo+'et 'bar/'sont les nombres premiers 1718578987 et 1650553391.


Exemples:

Ignore les zéros de tête:

echo -ne '\x00\x00\x00\x00' |./hash
0000000000000000

Entrées à un octet:

echo -ne '\x01' |./hash
0000000100000001
echo -ne '\xff' |./hash
000000ff000000ff

Entrées multi-octets:

echo -ne '\x01\x01' |./hash
666f6f2dc8d0e15c
echo -ne 'Hello, World' |./hash
04f1a7412b17b86c
ossifrage délirant
la source
Comment serait - il se comporter avec « aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa » et « aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa »?
Ismael Miguel
1
foo|(d5c9bef71d4f5d1b) et foo\(d5c9bef71d4f5d1b) produisent des hachages TRÈS similaires.
Ismael Miguel
1
L'a cassé!!! \x00et \x00\x00!
Ismael Miguel
1
Sur la base des commentaires du chat, je pense que cela n’est pas encore résolu? Juste une double vérification, parce que le commentaire voté peut être déroutant pour ceux qui recherchent des hachages non piratés.
Sp3000
2
Fissuré
Vi.
3

J - 39 octets - fissuré

Fonction prenant une chaîne en entrée et renvoyant un entier <2 128 . Je suppose que nous devons nommer notre fonction pour qu'elle soit valide; supprimez donc 3 caractères supplémentaires du compte si nous pouvons soumettre des fonctions anonymes.

H=:_8(".p:@+5,9:)a\(a=.(2^128x)&|@^/@)]

Pour ceux d'entre vous qui ne lisent pas les hiéroglyphes, voici un aperçu de ce que je fais.

  • a=.(2^128x)&|@^/@ Ceci est un sous-programme * qui prend un tableau de nombres, puis le traite comme une tour de puissance, où l’exponentiation est prise mod 2 128 . Par "tour de pouvoir", je veux dire que si vous lui fournissiez une entrée 3 4 5 6, elle calculerait 3 ^ (4 ^ (5 ^ 6)).
  • (".p:@+5,9:)aCette fonction prend une chaîne, la convertit en un nombre N , puis calcule les nombres premiers ( n +5) et les n premiers ( n +9), puis jette les aprécédents sur elle. C'est, nous trouvons le p(n+5) ^ p(n+9)mod 2 128p(k)est le k-th prime.
  • H=:_8...\(a...)]Effectuez la fonction ci-dessus sur les sous-blocs de 8 caractères de l'entrée, puis atous les résultats ensemble et appelez la fonction de hachage résultante H. J'utilise 8 caractères parce que la fonction " k-th prime" de J échoue lorsque p(k)> 2 31 , c'est k=105097564-à- dire le coffre-fort le plus grand k.

Avoir quelques exemples de sorties. Vous pouvez essayer cela vous-même en ligne sur tryj.tk , mais je vous le recommande vivement en téléchargeant l'interprète de Jsoftware .

   H=:_8(".p:@+5,9:)a\(a=.(2^128x)&|@^/@)]
   H '88'
278718804776827770823441490977679256075
   H '0'
201538126434611150798503956371773
   H '1'
139288917338851014461418017489467720433
   H '2'
286827977638262502014244740270529967555
   H '3'
295470173585320512295453937212042446551
   30$'0123456789'  NB. a 30 character string
012345678901234567890123456789
   H 30$'0123456789'
75387099856019963684383893584499026337
   H 80$'0123456789'
268423413606061336240992836334135810465

* Techniquement, ce n'est pas une fonction en soi, il s'attache à d'autres fonctions et agit sur leur sortie. Mais c’est une question sémantique de J, pas une différence conceptuelle: le déroulement du programme est tel que je l’ai décrit ci-dessus.

algorithmeshark
la source
Cracked
SP3000
2

Python 3, 118 octets [ fissuré ]

def H(I):
    o=0;n=3;M=1<<128
    for c in I:i=ord(c);o=(o<<i^o^i^n^0x9bb90058bcf52d3276a7bf07bcb279b7)%M;n=n*n%M
    return o

L'indentation est un seul onglet. Simple hash, je ne l'ai pas encore vraiment testé.

Appeler comme suit:

print(H("123456789"))

résultat: 73117705077050518159191803746489514685

tomsmeding
la source
Comment convertir le nombre entier en entrée en chaîne à utiliser dans votre algorithme?
Feersum
@feersum base 10 est ce que j'ai testé. Il n’utilise rien d’autre part ord(c)que toute chaîne conviendra :) (sauf des caractères tels que des caractères nuls, je pense que ceux-ci facilitent les collisions de hachage. Conservez-vous donc avec une chaîne 0-9.)
Conservez
1
Je l'ai cassé: codegolf.stackexchange.com/a/51160/41288 . Commençons par observer que des chaînes telles que "10000" et "20000" produisent des hachages très proches. Commencé à jouer avec de plus en plus de zéros, et après 128 environ, tout chiffre + k * 4 répétitions de zéros retournent le même hachage indépendamment de k.
tucuxi
@tucuxi Déjà pensé qu'il ne devrait pas être abeille trop dur; heureux que ce ne soit pas trivial mais que quelqu'un l'a cassé quand même. Bon travail.
tomsmeding
2

C ++, 239 octets

Mon tout premier code golf! [ S'il vous plaît soyez doux ]

#define r(a,b) ((a<<b)|(a>>(64-b)))
typedef uint64_t I;I f(I*q, I n, I&h){h=0;for(I i=n;--i;)h=r(h^(r(q[i]*0x87c37b91114253d5,31)*0x4cf5ad432745937f),31)*5+0x52dce729;h^=(h>>33)*0xff51afd7ed558ccd;h^=(h>>33)*0xc4ceb9fe1a85ec53;h^=(h>>33);}

Version non-golfée:

I f(I* q, I n, I& h) // input, length and output
{
    h = 0; // initialize hashes
    for (I i=n;--i;)
    {
        q[i] *= 0x87c37b91114253d5;
        q[i]  = rotl(q[i], 31);
        q[i] *= 0x4cf5ad432745937f;

        h ^= q[i]; // merge the block with hash

        h *= rotl(h, 31);
        h = h * 5 + 0x52dce729;
    }
    h ^= h>>33;
    h *= 0xff51afd7ed558ccd;
    h ^= h>>33;
    h *= 0xc4ceb9fe1a85ec53; // avalanche!
    h ^= h>>33;
}

Pas le meilleur hash, et certainement pas le code le plus court existant. Accepter les astuces de golf et espérer s'améliorer!

Wrapper

Probablement pas le meilleur au monde, mais un emballage quand même

I input[500];

int main()
{
    string s;
    getline(cin, s);
    memcpy(input, s.c_str(), s.length());
    I output;
    f(input, 500, output);
    cout << hex << output << endl;
}
SpelingMistake
la source
2
Cela semble solide, mais avec 64 bits, il peut être sujet à des brutes. Il y a environ 50% de chances de trouver une collision dans les tests de ~ sqrt (n) (parmi n sorties totales); 2 ^ 32 essais n’est pas si important pour un PC moderne.
tucuxi
Wrapper manque d'inclusions d'en-tête et conduit en général à beaucoup de hachages égaux.
Vi.
Fournir des échantillons de hachage. Pour moi, "3" et "33" conduisent à 481c27f26cba06cf (en utilisant cette enveloppe).
Vi.
Craquelé : codegolf.stackexchange.com/a/51215/41288 . Je soupçonne juste avant @Vi. découvert pourquoi autant de hachages étaient égaux.
Tucuxi
1
Collision correcte (sans utilisation de bug): printf '33333333\x40\xF3\x32\xD6\x56\x91\xCA\x66' | ./hash7_-> a4baea17243177fd; printf '33333333\x77\x39\xF3\x82\x93\xDE\xA7\x2F' | ./hash7_-> a4baea17243177fd. Le bruteforcer détecte les collisions ici beaucoup plus rapidement que dans d'autres hachages 64 bits.
Vi.
2

Java, 299 291 282 octets, fissuré.

import java.math.*;class H{public static void main(String[]a){BigInteger i=new java.util.Scanner(System.in).nextBigInteger();System.out.print(BigInteger.valueOf(i.bitCount()*i.bitLength()+1).add(i.mod(BigInteger.valueOf(Long.MAX_VALUE))).modPow(i,BigInteger.valueOf(2).pow(128)));}}

Fait quelques opérations sur BigIntegers, prend ensuite le résultat modulo 2 128 .

SuperJedi224
la source
Comment je fais ça? Ideone refuse de le compiler.
Martin Ender
1
Vous pouvez l'exécuter sur Ideone en renommant la classe en "Main" ou en supprimant le premier mot clé "public" (mais PAS le second). Soit on travaillera.
SuperJedi224
Fissuré.
Martin Ender
1
@ SuperJedi224 Pourquoi ne pas supprimer le premier publicvous-même, en sauvant 7 caractères?
user253751
@immibis Parce qu'alors, je ne pense pas que cela fonctionnerait correctement avec Eclipse. Je vais l'essayer quand même. EDIT: Je suppose que c'est le cas. C'est une surprise.
SuperJedi224
2

C, 128 octets [ fissuré ]

p;q;r;s;main(c){while((c=getchar())+1)p=p*'foo+'+s^c,q=q*'bar/'+p,r=r*'qux3'^q,s=s*'zipO'+p;printf("%08x%08x%08x%08x",p,q,r,s);}

C'est plus ou moins le même algorithme que mon dernier effort (craqué par Vi.) , Mais il a maintenant assez de roues de hamster pour générer le hachage à 128 bits approprié.

Les quatre constantes principales du code sont les suivantes:

'foo+' = 1718578987
'bar/' = 1650553391
'qux3' = 1903523891
'zipO' = 2053730383

Comme auparavant, il s’agit d’un programme complet ne nécessitant pas de wrapper. L'entier I est entré via stdin sous forme de données binaires brutes (big-endian), et le hachage O est imprimé en hexadécimal vers stdout. Les zéros non significatifs dans I sont ignorés.

Exemples:

echo -ne '\x00' |./hash
00000000000000000000000000000000
echo -ne '\x00\x00' |./hash
00000000000000000000000000000000
echo -ne '\x01' |./hash
00000001000000010000000100000001
echo -ne 'A' |./hash
00000041000000410000004100000041
echo -ne '\x01\x01' |./hash
666f6f2dc8d0e15cb9a5996fe0d8df7c
echo -ne 'Hello, World' |./hash
da0ba2857116440a9bee5bb70d58cd6a
ossifrage délirant
la source
1
Cracked codegolf.stackexchange.com/a/51216/101
aaaaaaaaaaaaa
Votre exemple n’a-t-il pas montré une collision juste là (les deux premiers)?
mbomb007
@ mbomb007 Non. L'entrée est un nombre compris entre 0 et 2 ^ (2 ^ 30). 0x00 et 0x0000 sont tous deux égaux à zéro et produisent donc la même sortie.
ossifrage
2

C, 122 octets [ fissuré ]

long long x,y,p;main(c){for(c=9;c|p%97;c=getchar()+1)for(++p;c--;)x=x*'[3QQ'+p,y^=x^=y^=c*x;printf("%016llx%016llx",x,y);}

Boucles imbriquées, GCL à moitié calibrés et permutation de variables. Qu'est-ce qu'il n'y a pas à aimer?

Voici une version non-golfée avec laquelle jouer:

long long x,y,p;

int main(int c){
    // Start with a small number of iterations to
    //   get the state hashes good and mixed because initializing takes space
    // Then, until we reach the end of input (EOF+1 == 0)
    //   and a position that's a multiple of 97
    for (c=9;c|p%97;c=getchar()+1) {

        // For each input c(haracter) ASCII value, iterate down to zero
        for (++p;c--;) {

            // x will act like a LCG with a prime multiple
            //   partially affected by the current input position
            // The string '[3QQ' is the prime number 0x5B335151
            x=x*'[3QQ'+p;

            // Mix the result of x with the decrementing character
            y^=c*x;

            // Swap the x and y buffers
            y^=x^=y;
        }
    }

    // Full 128-bit output
    printf("%016llx%016llx",x,y);
    return 0;
}

Il s'agit d'un programme entièrement autonome qui lit à partir de STDIN et imprime vers STDOUT.

Exemple:

> echo -n "Hello world" | ./golfhash
b3faef341f70c5ad6eed4c33e1b55ca7

> echo -n "" | ./golfhash
69c761806803f70154a7f816eb3835fb

> echo -n "a" | ./golfhash
5f0e7e5303cfcc5ecb644cddc90547ed

> echo -n "c" | ./golfhash
e64e173ed4415f7dae81aae0137c47e5

Dans certains tests simples, il se situe autour de 3 Mo / s de données texte. La vitesse de hachage dépend des données d'entrée elles-mêmes, vous devriez donc probablement en tenir compte.

M. Lama
la source
1
Cracked: codegolf.stackexchange.com/a/51354/101
aaaaaaaaaaaa
1

PHP 4.1, 66 octets [ fissuré ]

Je suis juste en train de me réchauffer.

J'espère que vous trouvez cela instinctif.

<?for($l=strlen($b.=$a*1);$i<40;$o.=+$b[+$i]^"$a"/$a,$i++);echo$o;

J'ai essayé des nombres aussi grands que 999999999999999999999999999.
La sortie semblait se situer dans la plage 2 128 .


PHP 4.1 est requis en raison de la register_globals directive.

Cela fonctionne en créant automatiquement des variables locales à partir de la session, POST, GET, REQUEST et des cookies.

Il utilise la clé a. (EG: accès par dessus http://localhost/file.php?a=<number>).

Si vous voulez le tester avec PHP 4.2 et plus récent, essayez ceci:

<?for($l=strlen($b.=$a=$_REQUEST['a']*1);$i<40;$o.=+$b[+$i]^"$a"/$a,$i++);echo$o;

Cette version ne fonctionne qu'avec POST et GET.


Exemple de sortie:

0 -> 0000000000000000000000000000000000000000
9 -> 8111111111111111111111111111111111111111
9999 -> 8888111111111111111111111111111111111111
1234567890 -> 0325476981111111111111111111111111111111
99999999999999999999999999999999999999999999999999999999999999999999999999999999 -> 0111191111111111111111111111111111111111

(Je vous assure qu'il y a des nombres qui produisent le même hash).

Ismael Miguel
la source
Craquelé
Vi.
1

C, 134 octets, fissuré

C'est le programme complet en C.

long long i=0,a=0,e=1,v,r;main(){for(;i++<323228500;r=(e?(scanf("%c",&v),e=v>'/'&&v<':',v):(a=(a+1)*7)*(7+r)));printf("0x%llx\n", r);}

Son effet: l’idée est de prendre l’entrée sous forme de tableau d’octets et d’ajouter à la fin des octets pseudo-aléatoires (mais déterministes) pour que la longueur soit égale à environ 2 2 30 (un peu plus). L'implémentation lit entrée par octet et commence à utiliser des données pseudo aléatoires lorsqu'elle trouve le premier caractère qui n'est pas un chiffre.

Comme PRNG intégré n'est pas autorisé, je l'ai mis en œuvre moi-même.

Il existe un comportement non défini / défini par l'implémentation qui raccourcit le code (la valeur finale doit être non signée et je dois utiliser différents types pour différentes valeurs). Et je ne pouvais pas utiliser les valeurs 128 bits en C. Version moins obscurcie:

long long i = 0, prand = 0, notEndOfInput = 1, in, hash;

main() {
    for (; i++ < 323228500;) {
        if (notEndOfInput) {
            scanf("%c", &in);
            notEndOfInput = in >= '0' && in <= '9';
            hash = in;
        } else {
            prand = (prand + 1)*7;
            hash = prand*(7 + hash);
        }
    }
    printf("0x%llx\n", hash);
}
barteks2x
la source
Cracked
dégoûté orfraie
1

Python 2.X - 139 octets [[ fissuré ]]

Ceci est assez similaire à tous les autres hachages (LOOP, XOR, SHIFT, ADD) ici. Venez chercher vos voleurs de points;) Je vais en faire un plus dur une fois celui-ci résolu.

M=2**128
def H(I):
 A=[1337,8917,14491,71917];O=M-I%M
 for z in range(73):
  O^=A[z%4]**(9+I%9);O>>=3;O+=9+I**(A[z%4]%A[O%4]);O%=M
 return O

Wrapper (attend un argument en base 16 également appelé hexadécimal):

import sys
if __name__ == '__main__':
 print hex(H(long(sys.argv[1], 16)))[2:][:-1].upper()
Puzzled
la source
1
De plus, je ne suis pas sûr que cette entrée soit conforme aux spécifications de l'OP, car sur ma machine, la fonction prend plusieurs secondes pour les entrées de grande taille. Par exemple, a H(2**(2**10))pris environ 8 ou 9 secondes, alors qu’il a H(2**(2**12))fallu environ 29 secondes et H(2**(2**14))plus de deux minutes.
mathmandan
Vous avez absolument raison, j'aurais évidemment dû tester le timing pour des entrées plus importantes. De plus, il semble que j'ai oublié de lancer mon propre test après l’ajout de ce poste. La version originale était sans décalage (avant la publication) et réussissait mon test "Pas de collisions dans les 100 000 premiers entiers": /
Intrigué, le
1

Python 2.7 - 161 octets [[ Cracked ]]

Eh bien, puisque j'ai réussi à changer ma première fonction de hachage en une version inutile avant de la publier, je pense que je publierai une autre version d'une structure similaire. Cette fois-ci, je l'ai testé contre des collisions triviales et la plupart des magnitudes d'entrée possibles pour la vitesse.

A=2**128;B=[3,5,7,11,13,17,19]
def H(i):
 o=i/A
 for r in range(9+B[i%7]):
  v=B[i%7];i=(i+o)/2;o=o>>v|o<<128-v;o+=(9+o%6)**B[r%6];o^=i%(B[r%6]*v);o%=A
 return o

Wrapper (non compté dans le bytecount)

import sys
if __name__ == '__main__':
 arg = long(sys.argv[1].strip(), 16)
 print hex(H(arg))[2:][:-1].upper()

Exemple d'exécution (l'entrée est toujours un nombre hexadécimal):

$ python crypt2.py 1
3984F42BC8371703DB8614A78581A167
$ python crypt2.py 10
589F1156882C1EA197597C9BF95B9D78
$ python crypt2.py 100
335920C70837FAF2905657F85CBC6FEA
$ python crypt2.py 1000
B2686CA7CAD9FC323ABF9BD695E8B013
$ python crypt2.py 1000AAAA
8B8959B3DB0906CE440CD44CC62B52DB
Perplexe
la source
1
Fissuré .
jimmy23013
Bien joué jimmy :)
Intrigué le
1

Ruby, 90 octets

def H(s);i=823542;s.each_byte{|x|i=(i*(x+1)+s.length).to_s.reverse.to_i%(2**128)};i;end

Un algorithme de hachage hautement aléatoire que j'ai créé sans regarder aucun hachage réel ... aucune idée si c'est bon. il faut une chaîne en entrée.

Wrapper:

def buildString(i)
  if(i>255)
    buildString(i/256)+(i%256).chr
  else
    i.chr
  end
end 
puts H buildString gets
MegaTom
la source
Could you please provide the wrapper the question requires?
Dennis
What's the input format? I tried with a number but it says comparison of String with 255 failed (ArgumentError).
jimmy23013
H takes a string, Build string takes the number required by the OP and transforms it to a string.
MegaTom
I think you need a gets.to_i in the wrapper.
jimmy23013
Cracked.
jimmy23013
0

Mathematica, 89 bytes, cracked

Last@CellularAutomaton[(a=Mod)[#^2,256],{#~IntegerDigits~2,0},{#~a~99,128}]~FromDigits~2&

Not the shortest.

LegionMammal978
la source
3
How do you run this without Mathematica? "There should be a free (as in beer) compiler/interpreter that can be run on a x86 or x64 platform or from within a web browser."
Martin Ender
2
@MartinBüttner wolfram.com/mathematica/trial
LegionMammal978
Cracked.
Martin Ender
0

PHP, 79 Bytes (cracked. With a comment):

echo (('.'.str_replace('.',M_E*$i,$i/pi()))*substr(pi(),2,$i%20))+deg2rad($i);

This does alot of scary things via type-conversions in php, which makes it hard to predict ;) (or at least I hope so). It's not the shortest or most unreadable answer, however.

To run it you can use PHP4 and register globals (with ?i=123) or use the commandline:

php -r "$i = 123.45; echo (('.'.str_replace('.',M_E*$i,$i/pi()))*substr(pi(),2,$i%20))+deg2rad($i);"
Sebb
la source
5
The hash's output value looks floating-point. And It's the same for 3000000000000000000000000000000000000000000001 and 3000000000000000000000000000000000000000000000.
Vi.
0

C# - 393 bytes cracked

using System;class P{static void Main(string[]a){int l=a[0].Length;l=l%8==0?l/8:l/8+1;var b=new byte[l][];for(int i=0;i<l;i++){b[i]=new byte[8];};int j=l-1,k=7;for(int i=0;i<a[0].Length;i++){b[j][k]=Convert.ToByte(""+a[0][i],16);k--;if((i+1)%8==0){j--;k=7;}}var c=0xcbf29ce484222325;for(int i=0;i<l;i++){for(int o=0;o<8;o++){c^=b[i][o];c*=0x100000001b3;}}Console.WriteLine(c.ToString("X"));}}

Ungolfed:

using System;
class P
{
    static void Main(string[]a)
    {
      int l = a[0].Length;
      l = l % 8 == 0 ? l / 8 : l / 8 + 1;
      var b = new byte[l][];
      for (int i = 0; i < l; i++) { b[i] = new byte[8]; };
      int j = l-1, k = 7;
      for (int i = 0; i < a[0].Length; i++)
      {
        b[j][k] = Convert.ToByte(""+a[0][i], 16);
        k--;
        if((i+1) % 8 == 0)
        {
          j--;
          k = 7;
        }
      }
      var c = 0xcbf29ce484222325;
      for (int i = 0; i < l; i++)
      {
        for (int o = 0; o < 8; o++)
        {
          c ^= b[i][o];
          c *= 0x100000001b3;
        }
      }
      Console.WriteLine(c.ToString("X"));
    }
}

I have never touched cryptography or hashing in my life, so be gentle :)

It's a simple implementation of an FNV-1a hash with some array pivoting on the input. I am sure there is a better way of doing this but this is the best I could do.

It might use a bit of memory on long inputs.

ldam
la source
Cracked: codegolf.stackexchange.com/a/51277/101 On top of having faulty padding, this is not a cryptographic hash, there is so many ways to break it.
aaaaaaaaaaaa
0

Python 2, 115 bytes [Cracked already!]

OK, here's my last effort. Only 115 bytes because the final newline isn't required.

h,m,s=1,0,raw_input()
for c in[9+int(s[x:x+197])for x in range(0,len(s),197)]:h+=pow(c,257,99**99+52)
print h%4**64

This is a complete program that inputs a decimal integer on stdin and prints a decimal hash value on stdout. Extra leading zeroes will result in different hash values, so I'll just assume that the input doesn't have any.

This works by stuffing 197-digit chunks of the input number through a modular exponentiation. Unlike some languages, the int() function always defaults to base 10, so int('077') is 77, not 63.

Sample outputs:

$ python hash.py <<<"0"
340076608891873865874583117084537586383

$ python hash.py <<<"1"
113151740989667135385395820806955292270

$ python hash.py <<<"2"
306634563913148482696255393435459032089

$ python hash.py <<<"42"
321865481646913829448911631298776772679

$ time python hash.py <<<`python <<<"print 2**(2**19)"`
233526113491758434358093601138224122227

real    0m0.890s   <-- (Close, but fast enough)
user    0m0.860s
sys     0m0.027s
squeamish ossifrage
la source
1
It didn't use the order of blocks... Cracked.
jimmy23013
Ugh. I give in :-(
squeamish ossifrage