การนำอัลกอริทึมแฮช SHA-1 มาใช้


15

เป้าหมายของ code-golf นี้คือการสร้างโปรแกรมที่รับสตริงเป็นอินพุตและคุณต้องส่งออกค่าแฮชSHA-1เป็นเลขฐานสิบหก คุณสามารถค้นหารหัสเทียมสำหรับ SHA-1 ได้ที่นี่

กฎอื่น ๆ :

  1. ไม่มีการเข้าถึงเครือข่าย
  2. คุณไม่ได้รับอนุญาตให้เรียกใช้โปรแกรมภายนอก
  3. คุณไม่ได้รับอนุญาตให้ใช้วิธีการในตัวเพื่อแฮชอินพุต
  4. รหัสที่สั้นที่สุดชนะ
  5. มีความจำเป็นเพียงจัดการกับอินพุต ASCII เท่านั้น
  6. เอาต์พุตอาจเป็นตัวพิมพ์เล็กหรือตัวพิมพ์ใหญ่
  7. อินพุตสามารถจัดเตรียมโดยใช้:

    1. พรอมต์สำหรับการป้อนข้อมูล
    2. การใช้อาร์กิวเมนต์บรรทัดคำสั่ง
    3. ใช้ STDIN

กรณีทดสอบ:

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

คำตอบ:


5

GolfScript, 374 322 ตัวอักษร

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

สิ่งนี้มีพื้นฐานมาจากการใช้งานรหัสเทียมใน GolfScript รวมถึงการเข้ารหัสเล็กน้อยเพื่อย่อรหัสให้สั้นลง (ลองออนไลน์ ) อินพุตจะถูกอ่านจาก STDIN


นี่เป็น GolfScript ที่ยาวที่สุดที่ฉันเคยเห็น: P
Doorknob

5

Python 3 - 645 ตัวอักษร

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

เป็น pseudocode เวอร์ชัน golfed


utf = u8 ใน python3 หรือไม่
คุณ

1
@YOU ใช่มันก็ใช้ได้เหมือนกัน ฉันเพิ่งตรวจสอบและปรากฎว่า.encode()ใช้ UTF-8 ตามค่าเริ่มต้นซึ่งสั้นกว่า
grc

2

D (759 ตัวอักษร)

เวอร์ชันที่สามารถเรียกทำงานออนไลน์ได้: 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 ตัวอักษร

โปรแกรมคำนวณ SHA-1 ของเนื้อหาของอินพุตมาตรฐาน

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

หมายเหตุสองประการ:

  1. โปรแกรมนี้ถือว่าintมีขนาด 32 บิตอย่างแน่นอน สำหรับแพลตฟอร์มที่ไม่ใช่กรณีนี้การunsignedประกาศที่จุดเริ่มต้นที่ดีควรถูกแทนที่ด้วยประเภท 32 บิตที่ไม่ได้ลงนามของแพลตฟอร์ม ( uint32_tจะเป็นตัวเลือกที่ชัดเจนหากไม่ต้องการ#include <stdint.h> )
  2. โปรแกรมนี้ถือว่าเป็นแพลตฟอร์มเล็ก ๆ น้อย ๆ สำหรับแพลตฟอร์มขนาดใหญ่เพียงแค่ลบทั้งสองเหตุการณ์^3ในโปรแกรมและแทนที่การเริ่มต้นk[]ด้วยบล็อกต่อไปนี้: {19088743,0x89ABCDEF,0,1985229328,0xF0E1D2C3}สำหรับขนาด 541 ตัวอักษร
  3. สำหรับการใช้งานที่charไม่ได้ลงนามโดยค่าเริ่มต้นหนึ่งสามารถลบ&255ที่ปรากฏในบรรทัดสุดท้ายเพื่อบันทึกตัวละครอีกสี่ตัว

ผลตอบแทนนี้be417768b5c3c5c1d9bcb2e7c119196dd76b5570สำหรับThe quick brown fox jumps over the lazy dogแต่มันก็มีที่จะกลับมา2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
ProgramFOX

@ProgramFOX นั่นคือค่าแฮชสำหรับสตริงบวกกับการยกเลิกบรรทัดใหม่ ค่าทดสอบ SHA-1 ที่ยกมาในคำอธิบายนั้นใช้สำหรับสตริงโดยไม่ต้องยกเลิกบรรทัดใหม่ดังนั้นจึงไม่ต้องเพิ่มบรรทัดใหม่ให้กับอินพุตหากคุณต้องการทดสอบสตริงเหล่านั้น
breadbox

1

รหัสหลามของฉันยาวขึ้นเล็กน้อย แต่ก็ทำงานได้อย่างสมบูรณ์

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)

โปรดระบุภาษาในคำตอบ นอกจากนี้เนื่องจากนี่คือ code-golf อย่างน้อยคุณควรพยายามลดขนาด ชื่อตัวแปรแบบอักขระเดียวลบช่องว่างที่ไม่จำเป็นออกและยังคงค่าคงที่ราคาแพง ( 0xffffffff) เป็นตัวแปร (เช่นนั้นจะ-1พอเพียงหรือไม่?) ...
John Dvorak

ดูเหมือน phython ให้ฉัน :)
Owais Qureshi

@JanDvorak ฉันแก้ไขรหัสของฉัน
kyle k

h0..h4ยังคงเป็นตัวอักษรสองตัว ;-)
John Dvorak

ฉันได้รับข้อผิดพลาดทางไวยากรณ์ที่บรรทัด 29
ProgramFOX
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.