Implementierung des SHA-1-Hash-Algorithmus


15

Das Ziel dieses Code-Golfs ist es, ein Programm zu erstellen, das einen String als Eingabe verwendet, und Sie müssen den SHA-1- Hashwert als Hexadezimalzahl ausgeben . Den Pseudocode für SHA-1 finden Sie hier

Andere Regeln:

  1. Kein Netzwerkzugriff
  2. Sie dürfen keine externen Programme ausführen
  3. Es ist nicht gestattet, integrierte Methoden zum Hashing der Eingabe zu verwenden
  4. Der kürzeste Code gewinnt
  5. Es muss nur die ASCII-Eingabe verarbeitet werden
  6. Die Ausgabe kann entweder in Klein- oder Großbuchstaben erfolgen
  7. Die Eingabe kann erfolgen mit:

    1. Eingabeaufforderung
    2. Verwenden von Befehlszeilenargumenten
    3. STDIN verwenden

Testfälle:

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

Antworten:


5

GolfScript, 374 322 Zeichen

[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>}%''+

Dies basiert auf einer genauen Implementierung des Pseudocodes in GolfScript und einigen kleineren Codierungen, um den Code zu verkürzen (versuchen Sie es online ). Die Eingabe wird von STDIN gelesen.


Dies ist das längste GolfScript, das ich je gesehen habe: P
Türklinke

5

Python 3 - 645 Zeichen

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]))

Nur eine Golfversion des Pseudocodes.


funktioniert utf = u8 in python3?
SIE

1
@YOU Ja, das funktioniert auch. Ich habe es gerade überprüft und es stellt sich heraus, dass .encode()standardmäßig UTF-8 verwendet wird, was sogar noch kürzer ist.
Grc

2

D (759 Zeichen)

Online ausführbare Version: 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 Zeichen

Das Programm berechnet das SHA-1 aus dem Inhalt seiner Standardeingabe.

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

Ein paar Notizen:

  1. Dieses Programm geht von intgenau 32 Bit aus. Für Plattformen, auf denen dies nicht der Fall ist, sollte die unsignedDeklaration ganz am Anfang durch den vorzeichenlosen 32-Bit-Typ der Plattform ersetzt werden. ( uint32_twäre die naheliegende Wahl, wenn es nicht erforderlich wäre #include <stdint.h>.)
  2. Dieses Programm setzt eine Little-Endian-Plattform voraus. Entfernen Sie für eine Big-Endian-Plattform einfach die beiden Vorkommen ^3im Programm und ersetzen Sie die Initialisierung k[]durch den folgenden Block: {19088743,0x89ABCDEF,0,1985229328,0xF0E1D2C3}für eine Größe von 541 Zeichen.
  3. Bei Implementierungen, bei denen charstandardmäßig kein Vorzeichen angegeben ist, kann das &255in der letzten Zeile angezeigte Zeichen gelöscht werden, um vier weitere Zeichen zu speichern.

Dies kehrt be417768b5c3c5c1d9bcb2e7c119196dd76b5570für zurück, The quick brown fox jumps over the lazy dogaber es muss zurückkehren2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
ProgramFOX

@ProgramFOX Dieser Hash-Wert gilt für den String plus einer abschließenden neuen Zeile. Die in der Beschreibung angegebenen Test-SHA-1-Werte gelten für Zeichenfolgen ohne abschließende Zeilenumbrüche. Fügen Sie der Eingabe also keine Zeilenumbrüche hinzu, wenn Sie diese Zeichenfolgen testen möchten.
Brotkasten

1

Mein Python-Code ist etwas länger, funktioniert aber voll.

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)

Bitte geben Sie die Sprache in der Antwort an. Da dies auch Code-Golf ist, sollten Sie zumindest eine Minimierung versuchen. Ein-Zeichen-Variablennamen, unnötige Leerzeichen entfernen, teure Konstanten ( 0xffffffff) in Variablen verstauen ( würde auch -1ausreichen?) ...
John Dvorak

sieht aus wie Phython für mich :)
Owais Qureshi

@ JanDvorak Ich habe meinen Code geändert.
Kyle K

h0..h4sind immer noch zwei Buchstaben ;-)
John Dvorak

Ich erhalte einen Syntaxfehler in Zeile 29.
ProgramFOX
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.