Implémentation de l'algorithme de hachage SHA-1


15

Le but de ce code-golf est de créer un programme qui prend une chaîne en entrée, et vous devez sortir la valeur de hachage SHA-1 sous forme de nombre hexadécimal. Vous pouvez trouver le pseudocode pour SHA-1 ici

Autres règles:

  1. Pas d'accès au réseau
  2. Vous n'êtes pas autorisé à exécuter des programmes externes
  3. Vous n'êtes pas autorisé à utiliser des méthodes intégrées pour hacher l'entrée
  4. Le code le plus court gagne
  5. Il est seulement nécessaire de gérer l'entrée ASCII
  6. La sortie peut être en minuscules ou en majuscules
  7. L'entrée peut être fournie en utilisant:

    1. Demander l'entrée
    2. Utilisation d'arguments de ligne de commande
    3. Utilisation de STDIN

Cas de test:

Input: The quick brown fox jumps over the lazy dog
Output: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
----------------------------------------------------------
Input: The quick brown fox jumps right over the lazy dog
Output: 1c3aff41d97ada6a25ae62f9522e4abd358d741f
------------------------------------------------------------
Input: This is a code golf challenge
Output: f52ff9edd95d98e707bd16a7dead459cb8db8693

Réponses:


5

GolfScript, 374 322 caractères

[128]+.,.~55+64%1,*\(8*2
32?:?.*+256{base}:B~1>++"!Vi9y BRQ+@phoKD5Vj=]30z0"{96@32-*+}*?B\64/{4/{256B}%{0'=820'{64-
2$=^}/2*.?/+?%+}64*1$'&4$?(^3$&|1518500249{++[]@+@+@?*4/.?/+?%+2$+\@32*.?/++@(@+?%@-1%+}:Y~
^2$^1859775393Y
&4$3$&|3$3$&|2400959708Y
^2$^3395469782Y'n/{'~3$3$'\+20*~}/+]zip{~+?%}%}/{?+16B{.9>7*+48+}%1>}%''+

Ceci est basé sur une implémentation exacte du pseudo-code dans GolfScript plus quelques encodages mineurs pour raccourcir le code (essayez-le en ligne ). L'entrée sera lue à partir de STDIN.


Voici le GolfScript le plus long que j'ai jamais vu: P
Poignée de porte

5

Python 3 - 645 caractères

h=0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0
L=lambda v,s:(v<<s|v>>B-s)%2**B
B=32
R=range
m=input().encode()
l=len(m)
m+=b'\x80'+bytes((55-l)%64)+m.fromhex(hex(2**64+l*8)[3:])
for C in [m[i:i+64]for i in R(0,len(m),64)]:
 w=[sum(C[i+j]<<8*(3-j)for j in R(4))for i in R(0,64,4)];a,b,c,d,e=h
 for i in R(16,80):w+=[L(w[i-3]^w[i-8]^w[i-14]^w[i-16],1)]
 for i in R(80):f=[b&c|~b&d,b^c^d,b&c|b&d|c&d,b^c^d][i//20];k=[0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6][i//20];t=L(a,5)+f+e+k+w[i];e=d;d=c;c=L(b,30);b=a;a=t%2**32
 g=a,b,c,d,e;h=[(h[i]+g[i])%2**32for i in R(5)]
B=160
print('%x'%(L(h[0],128)|L(h[1],96)|L(h[2],64)|L(h[3],32)|h[4]))

Juste une version golfée du pseudocode.


utf = u8 en python3?
VOUS du

1
@YOU Oui, ça marche aussi. Je viens de vérifier et il s'avère que l' .encode()UTF-8 utilise par défaut, ce qui est encore plus court.
grc

2

D (759 caractères)

Version exécutable en ligne: http://dpaste.dzfl.pl/f0c8508f

import std.range,std.algorithm,std.bitmanip,std.stdio:g=writef;
void main(char[][]x){
    auto m=cast(ubyte[])x[1];
    uint a=0x67452301,b=0xEFCDAB89,i,t,f,k;
    uint[5]h=[a,b,~a,~b,0xC3D2E1F0],s;
    uint[80]w;
    auto r=(uint u,uint b)=>u<<b|u>>32-b;
    auto u=(uint i)=>[r(s[0],5)+f+s[4]+k+w[i],s[0],r(s[1],30),s[2],s[3]];
    ubyte[64]p;
    p[0]=128;
    m~=p[0..64-(m.length+8)%64]~nativeToBigEndian(8*m.length);
    foreach(ch;m.chunks(64)){
        16.iota.map!(i=>w[i]=ch[i*4..$][0..4].bigEndianToNative!uint).array;
        iota(16,80).map!(i=>w[i]=r(w[i-3]^w[i-8]^w[i-14]^w[i-16],1)).array;
        s=h;
        80.iota.map!(i=>(i<20?f=s[3]^s[1]&(s[2]^s[3]),k=0x5A827999:i<40?f=s[1]^s[2]^s[3],k=0x6ED9EBA1:i<60?f=s[1]&s[2]|s[3]&(s[1]|s[2]),k=0x8F1BBCDC:(f=s[1]^s[2]^s[3],k=0xCA62C1D6),s[]=u(i)[])).array;
        h[]+=s[];
    }
    g("%(%08x%)",h);
}

2

C, 546 caractères

Le programme calcule le SHA-1 du contenu de son entrée standard.

unsigned b[16],k[]={1732584193,0xEFCDAB89,0,271733878,0xC3D2E1F0},i,j,n,p,t,u,v,w,x;
char*d=b;a(c){for(d[p++^3]=c,c=0,t=*k,u=k[1],v=k[2],w=k[3],x=k[4];
c>79?*k+=t,k[1]+=u,k[2]+=v,k[3]+=w,k[4]+=x,p=0:p>63;x=w,w=v,v=u<<30|u/4,u=t,t=i)
i=b[c-3&15]^b[c+8&15]^b[c+2&15]^b[j=c&15],c++>15?b[j]=i*2|i>>31:0,i=u^v^w,
i=(t<<5|t>>27)+x+b[j]+(c<21?(w^u&(v^w))+1518500249:c<41?i+1859775393:
c<61?(u&v|w&(u|v))-1894007588:i-899497514);}
main(){for(k[2]=~*k;i=~getchar();++n)a(~i);for(a(128);p-56;a(0));
for(;p<20?printf("%02x",(d=k)[p^3]&255):p>55;a(n*8L>>504-p*8));}

Quelques notes:

  1. Ce programme suppose que intc'est exactement 32 bits. Pour les plateformes où ce n'est pas le cas, la unsigneddéclaration au tout début doit être remplacée par le type 32 bits non signé de la plateforme. ( uint32_tserait le choix évident, s'il ne l'exigeait pas #include <stdint.h>.)
  2. Ce programme suppose une plateforme peu endienne. Pour une plateforme big-endian, supprimez simplement les deux occurrences de ^3dans le programme, et remplacez l'initialisation de k[]par le bloc suivant:, {19088743,0x89ABCDEF,0,1985229328,0xF0E1D2C3}pour une taille de 541 caractères.
  3. Pour les implémentations où charn'est pas signé par défaut, on peut supprimer celui &255qui apparaît sur la dernière ligne pour enregistrer quatre autres caractères.

Cela revient be417768b5c3c5c1d9bcb2e7c119196dd76b5570pour The quick brown fox jumps over the lazy dogmais il doit revenir2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
ProgramFOX

@ProgramFOX Cette valeur de hachage est pour la chaîne plus une nouvelle ligne de fin. Les valeurs de test SHA-1 citées dans la description sont pour les chaînes sans terminer les sauts de ligne, donc n'ajoutez pas de saut de ligne à l'entrée si vous voulez tester ces chaînes.
boîte à pain le

1

Mon code python est un peu plus long mais il fonctionne pleinement.

data="hello world"
bytes = ""
h0,h1,h2,h3,h4=0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0
for n in range(len(data)):bytes+='{0:08b}'.format(ord(data[n]))
bits=bytes+"1"
pBits=bits
while len(pBits)%512!=448:pBits+="0"
pBits+='{0:064b}'.format(len(bits)-1)
def chunks(l,n):return[l[i:i+n]for i in range(0,len(l),n)]
def rol(n,b):return((n<<b)|(n>>(32-b)))&0xffffffff 
for c in chunks(pBits,4512):
    words=chunks(c,32)
    w=[0]*80
    for n in range(0,16):w[n]=int(words[n],2)
    for i in range(16,80):w[i]=rol((w[i-3]^w[i-8]^w[i-14]^w[i-16]),1)
    a,b,c,d,e=h0,h1,h2,h3,h4
    for i in range(0,80):
        if 0<=i<=19:f=(b&c)|((~b)&d);k=0x5A827999
        elif 20<=i<=39:f=b^c^d;k=0x6ED9EBA1
        elif 40<=i<=59:f=(b&c)|(b&d)|(c&d);k=0x8F1BBCDC
        elif 60<=i<=79:f=b^c^d;k=0xCA62C1D6
        temp=rol(a,5)+f+e+k+w[i]&0xffffffff
        e,d,c,b,a=d,c,rol(b,30),a,temp 
    h0+=a
    h1+=b
    h2+=c
    h3+=d
    h4+=e 
print '%08x%08x%08x%08x%08x'%(h0,h1,h2,h3,h4)

Veuillez spécifier la langue dans la réponse. De plus, comme il s'agit de code-golf, vous devriez au moins tenter une minification. Noms de variables à un caractère, suppression d'espaces inutiles, stockage de constantes coûteuses ( 0xffffffff) dans des variables (cela -1suffirait-il également?) ...
John Dvorak

ressemble à du phython pour moi :)
Owais Qureshi

@JanDvorak J'ai modifié mon code.
kyle k

h0..h4sont toujours en deux lettres ;-)
John Dvorak

J'obtiens une erreur de syntaxe à la ligne 29.
ProgramFOX
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.