SHA-1
You are encouraged to solve this task according to the task description, using any language you may know.
SHA-1 or SHA1 is a one-way hash function; it computes a 160-bit message digest. SHA-1 often appears in security protocols; for example, many HTTPS websites use RSA with SHA-1 to secure their connections. BitTorrent uses SHA-1 to verify downloads. Git and Mercurial use SHA-1 digests to identify commits.
A US government standard, FIPS 180-1, defines SHA-1.
Find the SHA-1 message digest for a string of octets. You may either call a SHA-1 library, or implement SHA-1 in your language. Both approaches interest Rosetta Code.
AArch64 Assembly
<lang AArch64 Assembly> /* ARM assembly AARCH64 Raspberry PI 3B */ /* program sha1_64.s */
/*******************************************/ /* Constantes file */ /*******************************************/ /* for this file see task include a file in language AArch64 assembly*/ .include "../includeConstantesARM64.inc"
.equ SHA_DIGEST_LENGTH, 20
//.include "../../ficmacros64.s"
/*********************************/ /* Initialized data */ /*********************************/ .data szMessRosetta: .asciz "Rosetta Code" szMessTest1: .asciz "abc" szMessSup64: .ascii "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
.ascii "abcdefghijklmnopqrstuvwxyz" .asciz "1234567890AZERTYUIOP"
szMessTest2: .asciz "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" szMessFinPgm: .asciz "Program End ok.\n" szMessResult: .asciz "Rosetta Code => " szCarriageReturn: .asciz "\n"
/* array constantes Hi */ tbConstHi: .int 0x67452301 // H0
.int 0xEFCDAB89 // H1 .int 0x98BADCFE // H2 .int 0x10325476 // H3 .int 0xC3D2E1F0 // H4
/* array constantes Kt */ tbConstKt: .int 0x5A827999
.int 0x6ED9EBA1 .int 0x8F1BBCDC .int 0xCA62C1D6
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
iNbBlocs: .skip 8
sZoneConv: .skip 24
sZoneResult: .skip 24
sZoneTrav: .skip 1000
tbH: .skip 4 * 5 // 5 variables H
tbW: .skip 4 * 80 // 80 words W
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszMessRosetta //ldr x0,qAdrszMessTest1 //ldr x0,qAdrszMessTest2 //ldr x0,qAdrszMessSup64 bl computeSHA1 // call routine SHA1
ldr x0,qAdrszMessResult bl affichageMess // display message
ldr x0, qAdrsZoneResult bl displaySHA1
ldr x0,qAdrszMessFinPgm bl affichageMess // display message
100: // standard end of the program
mov x0,0 // return code mov x8,EXIT // request to exit program svc 0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn qAdrszMessResult: .quad szMessResult qAdrszMessRosetta: .quad szMessRosetta qAdrszMessTest1: .quad szMessTest1 qAdrszMessTest2: .quad szMessTest2 qAdrsZoneTrav: .quad sZoneTrav qAdrsZoneConv: .quad sZoneConv qAdrszMessFinPgm: .quad szMessFinPgm qAdrszMessSup64: .quad szMessSup64 /******************************************************************/ /* compute SHA1 */ /******************************************************************/ /* x0 contains the address of the message */ computeSHA1:
stp x1,lr,[sp,-16]! // save registers ldr x1,qAdrsZoneTrav mov x2,#0 // counter length
debCopy: // copy string in work area
ldrb w3,[x0,x2] strb w3,[x1,x2] cmp x3,#0 add x4,x2,1 csel x2,x4,x2,ne bne debCopy lsl x6,x2,#3 // initial message length in bits mov x3,#0b10000000 // add bit 1 at end of string strb w3,[x1,x2] add x2,x2,#1 // length in bytes lsl x4,x2,#3 // length in bits mov x3,#0
addZeroes:
lsr x5,x2,#6 lsl x5,x5,#6 sub x5,x2,x5 cmp x5,#56 beq storeLength // yes -> end add strb w3,[x1,x2] // add zero at message end add x2,x2,#1 // increment lenght bytes add x4,x4,#8 // increment length in bits b addZeroes
storeLength:
add x2,x2,#4 // add four bytes rev w6,w6 // inversion bits initials message length str w6,[x1,x2] // and store at end ldr x7,qAdrtbConstHi // constantes H address ldr x4,qAdrtbH // start area H mov x5,#0
loopConst: // init array H with start constantes
ldr w6,[x7,x5,lsl #2] // load constante str w6,[x4,x5,lsl #2] // and store add x5,x5,#1 cmp x5,#5 blt loopConst // split into block of 64 bytes add x2,x2,#4 // TODO : à revoir lsr x4,x2,#6 // blocks number ldr x0,qAdriNbBlocs str x4,[x0] // save block maxi mov x7,#0 // n° de block et x1 contient l'adresse zone de travail
loopBlock: // begin loop of each block of 64 bytes
mov x0,x7 bl inversion // inversion each word because little indian ldr x3,qAdrtbW // working area W address mov x6,#0 // indice t /* x2 address begin each block */ ldr x1,qAdrsZoneTrav add x2,x1,x7,lsl #6 // compute block begin indice * 4 * 16
loopPrep: // loop for expand 80 words
cmp x6,#15 // bgt expand1 ldr w0,[x2,x6,lsl #2] // load four byte message str w0,[x3,x6,lsl #2] // store in first 16 block b expandEnd
expand1:
sub x8,x6,#3 ldr w9,[x3,x8,lsl #2] sub x8,x6,#8 ldr w10,[x3,x8,lsl #2] eor x9,x9,x10 sub x8,x6,#14 ldr w10,[x3,x8,lsl #2] eor x9,x9,x10 sub x8,x6,#16 ldr w10,[x3,x8,lsl #2] eor x9,x9,x10 ror w9,w9,#31
str w9,[x3,x6,lsl #2]
expandEnd:
add x6,x6,#1 cmp x6,#80 // 80 words ? blt loopPrep // and loop /* COMPUTING THE MESSAGE DIGEST */ /* x1 area H constantes address */ /* x3 working area W address */ /* x5 address constantes K */ /* x6 counter t */ /* x7 block counter */ /* x8 a, x9 b, x10 c, x11 d, x12 e */
// init variable a b c d e ldr x0,qAdrtbH ldr w8,[x0] ldr w9,[x0,#4] ldr w10,[x0,#8] ldr w11,[x0,#12] ldr w12,[x0,#16] ldr x1,qAdrtbConstHi ldr x5,qAdrtbConstKt mov x6,#0
loop80T: // begin loop 80 t
cmp x6,#19 bgt T2 ldr w0,[x5] // load constantes k0 and x2,x9,x10 // b and c mvn w4,w9 // not b and x4,x4,x11 // and d orr x2,x2,x4 b T_fin
T2:
cmp x6,#39 bgt T3 ldr w0,[x5,#4] // load constantes k1 eor x2,x9,x10 eor x2,x2,x11 b T_fin
T3:
cmp x6,#59 bgt T4 ldr w0,[x5,#8] // load constantes k2 and x2,x9,x10 and x4,x9,x11 orr x2,x2,x4 and x4,x10,x11 orr x2,x2,x4 b T_fin
T4:
ldr w0,[x5,#12] // load constantes k3 eor x2,x9,x10 eor x2,x2,x11 b T_fin
T_fin:
ror w4,w8,#27 // left rotate a to 5 add w2,w2,w4 //affregtit Tfin 0 //affregtit Tfin 8 add w2,w2,w12 ldr w4,[x3,x6,lsl #2] // Wt add w2,w2,w4 add w2,w2,w0 // Kt mov x12,x11 // e = d mov x11,x10 // d = c ror w10,w9,#2 // c mov x9,x8 // b = a mov x8,x2 // nouveau a
add x6,x6,#1 // increment t cmp x6,#80 blt loop80T // other bloc add x7,x7,1 // increment block ldr x0,qAdriNbBlocs ldr w4,[x0] // restaur maxi block cmp x7,x4 // maxi ? bge End // End block ldr x0,qAdrtbH // start area H ldr w3,[x0] add w3,w3,w8 str w3,[x0] // store a in H0 ldr w3,[x0,#4] add w3,w3,w9 str w3,[x0,#4] // store b in H1 ldr w3,[x0,#8] add w3,w3,w10 str w3,[x0,#8] // store c in H2 ldr w3,[x0,#12] add w3,w3,w11 str w3,[x0,#12] // store d in H3 ldr w3,[x0,#16] add w3,w3,w12 str w3,[x0,#16] // store e in H4 b loopBlock // loop
End:
// compute final result ldr x0,qAdrtbH // start area H ldr x2,qAdrsZoneResult ldr w1,[x0] add x1,x1,x8 rev w1,w1 str w1,[x2] ldr w1,[x0,#4] add x1,x1,x9 rev w1,w1 str w1,[x2,#4] ldr w1,[x0,#8] add x1,x1,x10 rev w1,w1 str w1,[x2,#8] ldr w1,[x0,#12] add x1,x1,x11 rev w1,w1 str w1,[x2,#12] ldr w1,[x0,#16] add x1,x1,x12 rev w1,w1 str w1,[x2,#16] mov x0,#0 // routine OK
100:
ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30
qAdrtbConstHi: .quad tbConstHi qAdrtbConstKt: .quad tbConstKt qAdrtbH: .quad tbH qAdrtbW: .quad tbW qAdrsZoneResult: .quad sZoneResult qAdriNbBlocs: .quad iNbBlocs /******************************************************************/ /* inversion des mots de 32 bits d'un bloc */ /******************************************************************/ /* x0 contains N° block */ inversion:
stp x1,lr,[sp,-16]! // save registers stp x2,x3,[sp,-16]! // save registers ldr x1,qAdrsZoneTrav add x1,x1,x0,lsl 6 // debut du bloc mov x2,#0
1: // start loop
ldr w3,[x1,x2,lsl #2] rev w3,w3 str w3,[x1,x2,lsl #2] add x2,x2,#1 cmp x2,#16 blt 1b
100:
ldp x2,x3,[sp],16 // restaur 2 registers ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30
/******************************************************************/ /* display hash SHA1 */ /******************************************************************/ /* x0 contains the address of hash */ displaySHA1:
stp x1,lr,[sp,-16]! // save registers stp x2,x3,[sp,-16]! // save registers mov x3,x0 mov x2,#0
1:
ldr w0,[x3,x2,lsl #2] // load 4 bytes rev w0,w0 // reverse bytes ldr x1,qAdrsZoneConv bl conversion16_4W // conversion hexa ldr x0,qAdrsZoneConv bl affichageMess add x2,x2,#1 cmp x2,#SHA_DIGEST_LENGTH / 4 blt 1b // and loop ldr x0,qAdrszCarriageReturn bl affichageMess // display message
100:
ldp x2,x3,[sp],16 // restaur 2 registers ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30
/******************************************************************/ /* conversion hexadecimal register 32 bits */ /******************************************************************/ /* x0 contains value and x1 address zone receptrice */ conversion16_4W:
stp x0,lr,[sp,-48]! // save registres stp x1,x2,[sp,32] // save registres stp x3,x4,[sp,16] // save registres mov x2,#28 // start bit position mov x4,#0xF0000000 // mask mov x3,x0 // save entry value
1: // start loop
and x0,x3,x4 // value register and mask lsr x0,x0,x2 // right shift cmp x0,#10 // >= 10 ? bge 2f // yes add x0,x0,#48 // no is digit b 3f
2:
add x0,x0,#55 // else is a letter A-F
3:
strb w0,[x1],#1 // load result and + 1 in address lsr x4,x4,#4 // shift mask 4 bits left subs x2,x2,#4 // decrement counter 4 bits <= zero ? bge 1b // no -> loop
100: // fin standard de la fonction
ldp x3,x4,[sp,16] // restaur des 2 registres ldp x1,x2,[sp,32] // restaur des 2 registres ldp x0,lr,[sp],48 // restaur des 2 registres ret
/********************************************************/ /* File Include fonctions */ /********************************************************/ /* for this file see task include a file in language AArch64 assembly */ .include "../includeARM64.inc" </lang>
- Output:
Rosetta Code => 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5 Program End ok.
Ada
<lang Ada>with Ada.Text_IO; with GNAT.SHA1;
procedure Main is begin
Ada.Text_IO.Put_Line ("SHA1 (""Rosetta Code"") = " & GNAT.SHA1.Digest ("Rosetta Code"));
end Main;</lang>
- Output:
SHA1 ("Rosetta Code") = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
ARM Assembly
with openssl library <lang ARM Assembly>
/* ARM assembly Raspberry PI */ /* program sha1-1.s */ /* use with library openssl */ /* link with gcc option -lcrypto -lssl */
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly for the routine affichageMess conversion10 see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */ /************************************/ /* Constantes */ /************************************/ .include "../constantes.inc"
.equ SHA_DIGEST_LENGTH, 20
/*******************************************/ /* Fichier des macros */ /********************************************/ .include "../../ficmacros.s"
/*********************************/ /* Initialized data */ /*********************************/ .data szMessRosetta: .asciz "Rosetta Code"
.equ LGMESSROSETTA, . - szMessRosetta - 1
szCarriageReturn: .asciz "\n" szMessSup64: .ascii "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
.ascii "abcdefghijklmnopqrstuvwxyz" .asciz "1234567890AZERTYUIOP" .equ LGMESSSUP64, . - szMessSup64 - 1
szMessTest2: .asciz "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
.equ LGMESSTEST2, . - szMessTest2 - 1
/*********************************/ /* UnInitialized data */ /*********************************/ .bss .align 4 szMessResult: .skip 24 sZoneConv: .skip 24 /*********************************/ /* code section */ /*********************************/ .text .global main main: @ entry of program
ldr r0,iAdrszMessRosetta mov r1,#LGMESSROSETTA ldr r2,iAdrszMessResult bl SHA1 @ appel fonction openssl ldr r0,iAdrszMessResult bl displaySHA1
100: @ standard end of the program
mov r0, #0 @ return code mov r7, #EXIT @ request to exit program svc #0 @ perform the system call
iAdrszMessRosetta: .int szMessRosetta iAdrszCarriageReturn: .int szCarriageReturn iAdrszMessResult: .int szMessResult iAdrsZoneConv: .int sZoneConv iAdrszMessSup64: .int szMessSup64 iAdrszMessTest2: .int szMessTest2 /******************************************************************/ /* display hash SHA1 */ /******************************************************************/ /* r0 contains the address of hash */ displaySHA1:
push {r1-r3,lr} @ save registres mov r3,r0 mov r2,#0
1:
ldr r0,[r3,r2,lsl #2] @ load 4 bytes rev r0,r0 @ reverse bytes ldr r1,iAdrsZoneConv bl conversion16 @ conversion hexa ldr r0,iAdrsZoneConv bl affichageMess add r2,r2,#1 cmp r2,#SHA_DIGEST_LENGTH / 4 blt 1b @ and loop ldr r0,iAdrszCarriageReturn bl affichageMess @ display message
100:
pop {r1-r3,lr} @ restaur registers bx lr @ return
/***************************************************/ /* ROUTINES INCLUDE */ /***************************************************/ .include "../affichage.inc" </lang> with only instructions assembly ARM <lang> /* ARM assembly Raspberry PI */ /* program sha1.s */
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly for the routine affichageMess conversion10 see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */ /************************************/ /* Constantes */ /************************************/ .include "../constantes.inc"
.equ SHA_DIGEST_LENGTH, 20
.include "../../ficmacros.s"
/*********************************/ /* Initialized data */ /*********************************/ .data szMessRosetta: .asciz "Rosetta Code" szMessTest1: .asciz "abc" szMessSup64: .ascii "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
.ascii "abcdefghijklmnopqrstuvwxyz" .asciz "1234567890AZERTYUIOP"
szMessTest2: .asciz "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" szMessFinPgm: .asciz "Program End ok.\n" szMessResult: .asciz "Rosetta Code => " szCarriageReturn: .asciz "\n"
/* array constantes Hi */ tbConstHi: .int 0x67452301 @ H0
.int 0xEFCDAB89 @ H1 .int 0x98BADCFE @ H2 .int 0x10325476 @ H3 .int 0xC3D2E1F0 @ H4
/* array constantes Kt */ tbConstKt: .int 0x5A827999
.int 0x6ED9EBA1 .int 0x8F1BBCDC .int 0xCA62C1D6
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
iNbBlocs: .skip 4
sZoneConv: .skip 24
sZoneResult: .skip 24
sZoneTrav: .skip 1000
tbH: .skip 4 * 5 @ 5 variables H
tbW: .skip 4 * 80 @ 80 words W
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrszMessRosetta //ldr r0,iAdrszMessTest1 //ldr r0,iAdrszMessTest2 //ldr r0,iAdrszMessSup64 bl computeSHA1 @ call routine SHA1
ldr r0,iAdrszMessResult bl affichageMess @ display message
ldr r0, iAdrsZoneResult bl displaySHA1
ldr r0,iAdrszMessFinPgm bl affichageMess @ display message
100: @ standard end of the program
mov r0, #0 @ return code mov r7, #EXIT @ request to exit program svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn iAdrszMessResult: .int szMessResult iAdrszMessRosetta: .int szMessRosetta iAdrszMessTest1: .int szMessTest1 iAdrszMessTest2: .int szMessTest2 iAdrsZoneTrav: .int sZoneTrav iAdrsZoneConv: .int sZoneConv iAdrszMessFinPgm: .int szMessFinPgm iAdrszMessSup64: .int szMessSup64 /******************************************************************/ /* compute SHA1 */ /******************************************************************/ /* r0 contains the address of the message */ computeSHA1:
push {r1-r12,lr} @ save registres ldr r1,iAdrsZoneTrav mov r2,#0 @ counter length
debCopy: @ copy string in work area
ldrb r3,[r0,r2] strb r3,[r1,r2] cmp r3,#0 addne r2,r2,#1 bne debCopy lsl r6,r2,#3 @ initial message length in bits mov r3,#0b10000000 @ add bit 1 at end of string strb r3,[r1,r2] add r2,r2,#1 @ length in bytes lsl r4,r2,#3 @ length in bits mov r3,#0
addZeroes:
lsr r5,r2,#6 lsl r5,r5,#6 sub r5,r2,r5 cmp r5,#56 beq storeLength @ yes -> end add strb r3,[r1,r2] @ add zero at message end add r2,#1 @ increment lenght bytes add r4,#8 @ increment length in bits b addZeroes
storeLength:
add r2,#4 @ add four bytes rev r6,r6 @ inversion bits initials message length str r6,[r1,r2] @ and store at end ldr r7,iAdrtbConstHi @ constantes H address ldr r4,iAdrtbH @ start area H mov r5,#0
loopConst: @ init array H with start constantes
ldr r6,[r7,r5,lsl #2] @ load constante str r6,[r4,r5,lsl #2] @ and store add r5,r5,#1 cmp r5,#5 blt loopConst @ split into block of 64 bytes add r2,#4 @ TODO : à revoir lsr r4,r2,#6 @ blocks number ldr r0,iAdriNbBlocs str r4,[r0] @ save block maxi mov r7,#0 @ n° de block et r1 contient adresse zone de travail
loopBlock: @ begin loop of each block of 64 bytes
mov r0,r7 bl inversion @ inversion each word because little indian ldr r3,iAdrtbW @ working area W address mov r6,#0 @ indice t /* r2 address begin each block */ ldr r1,iAdrsZoneTrav add r2,r1,r7,lsl #6 @ compute block begin indice * 4 * 16 //vidregtit avantloop //mov r0,r2 //vidmemtit verifBloc r0 10
loopPrep: @ loop for expand 80 words
cmp r6,#15 @ bgt expand1 ldr r0,[r2,r6,lsl #2] @ load byte message str r0,[r3,r6,lsl #2] @ store in first 16 block b expandEnd
expand1:
sub r8,r6,#3 ldr r9,[r3,r8,lsl #2] sub r8,r6,#8 ldr r10,[r3,r8,lsl #2] eor r9,r9,r10 sub r8,r6,#14 ldr r10,[r3,r8,lsl #2] eor r9,r9,r10 sub r8,r6,#16 ldr r10,[r3,r8,lsl #2] eor r9,r9,r10 ror r9,r9,#31
str r9,[r3,r6,lsl #2]
expandEnd:
add r6,r6,#1 cmp r6,#80 @ 80 words ? blt loopPrep @ and loop /* COMPUTING THE MESSAGE DIGEST */ /* r1 area H constantes address */ /* r3 working area W address */ /* r5 address constantes K */ /* r6 counter t */ /* r7 block counter */ /* r8 a, r9 b, r10 c, r11 d, r12 e */ //ldr r0,iAdrtbW //vidmemtit verifW80 r0 20 @ init variable a b c d e ldr r0,iAdrtbH ldr r8,[r0] ldr r9,[r0,#4] ldr r10,[r0,#8] ldr r11,[r0,#12] ldr r12,[r0,#16] ldr r1,iAdrtbConstHi ldr r5,iAdrtbConstKt mov r6,#0
loop80T: @ begin loop 80 t
cmp r6,#19 bgt T2 ldr r0,[r5] @ load constantes k0 and r2,r9,r10 @ b and c mvn r4,r9 @ not b and r4,r4,r11 @ and d orr r2,r2,r4 b T_fin
T2:
cmp r6,#39 bgt T3 ldr r0,[r5,#4] @ load constantes k1 eor r2,r9,r10 eor r2,r11 b T_fin
T3:
cmp r6,#59 bgt T4 ldr r0,[r5,#8] @ load constantes k2 and r2,r9,r10 and r4,r9,r11 orr r2,r4 and r4,r10,r11 orr r2,r4 b T_fin
T4:
ldr r0,[r5,#12] @ load constantes k3 eor r2,r9,r10 eor r2,r11 b T_fin
T_fin:
ror r4,r8,#27 @ left rotate a to 5 add r2,r4 add r2,r12 ldr r4,[r3,r6,lsl #2] @ Wt add r2,r4 add r2,r0 @ Kt mov r12,r11 @ e = d mov r11,r10 @ d = c ror r10,r9,#2 @ c mov r9,r8 @ b = a mov r8,r2 @ nouveau a
add r6,r6,#1 @ increment t cmp r6,#80 blt loop80T @ other bloc add r7,#1 @ increment block ldr r0,iAdriNbBlocs ldr r4,[r0] @ restaur maxi block cmp r7,r4 @ maxi ? bge End @ End block ldr r0,iAdrtbH @ start area H ldr r3,[r0] add r3,r8 str r3,[r0] @ store a in H0 ldr r3,[r0,#4] add r3,r9 str r3,[r0,#4] @ store b in H1 ldr r3,[r0,#8] add r3,r10 str r3,[r0,#8] @ store c in H2 ldr r3,[r0,#12] add r3,r11 str r3,[r0,#12] @ store d in H3 ldr r3,[r0,#16] add r3,r12 str r3,[r0,#16] @ store e in H4 b loopBlock @ loop
End:
@ compute final result ldr r0,iAdrtbH @ start area H ldr r2,iAdrsZoneResult ldr r1,[r0] add r1,r8 rev r1,r1 str r1,[r2] ldr r1,[r0,#4] add r1,r9 rev r1,r1 str r1,[r2,#4] ldr r1,[r0,#8] add r1,r10 rev r1,r1 str r1,[r2,#8] ldr r1,[r0,#12] add r1,r11 rev r1,r1 str r1,[r2,#12] ldr r1,[r0,#16] add r1,r12 rev r1,r1 str r1,[r2,#16] mov r0,#0 @ routine OK
100:
pop {r1-r12,lr} @ restaur registers bx lr @ return
iAdrtbConstHi: .int tbConstHi iAdrtbConstKt: .int tbConstKt iAdrtbH: .int tbH iAdrtbW: .int tbW iAdrsZoneResult: .int sZoneResult iAdriNbBlocs: .int iNbBlocs /******************************************************************/ /* inversion des mots de 32 bits d un bloc */ /******************************************************************/ /* r0 contains N° block */ inversion:
push {r1-r3,lr} @ save registers ldr r1,iAdrsZoneTrav add r1,r0,lsl #6 @ debut du bloc mov r2,#0
1: @ start loop
ldr r3,[r1,r2,lsl #2] rev r3,r3 str r3,[r1,r2,lsl #2] add r2,r2,#1 cmp r2,#16 blt 1b
100:
pop {r1-r3,lr} @ restaur registres bx lr @return
/******************************************************************/ /* display hash SHA1 */ /******************************************************************/ /* r0 contains the address of hash */ displaySHA1:
push {r1-r3,lr} @ save registres mov r3,r0 mov r2,#0
1:
ldr r0,[r3,r2,lsl #2] @ load 4 bytes rev r0,r0 @ reverse bytes ldr r1,iAdrsZoneConv bl conversion16 @ conversion hexa ldr r0,iAdrsZoneConv bl affichageMess add r2,r2,#1 cmp r2,#SHA_DIGEST_LENGTH / 4 blt 1b @ and loop ldr r0,iAdrszCarriageReturn bl affichageMess @ display message
100:
pop {r1-r3,lr} @ restaur registers bx lr @ return
/***************************************************/ /* ROUTINES INCLUDE */ /***************************************************/ .include "../affichage.inc"
</lang>
- Output:
Rosetta Code => 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5 Program End ok.
Arturo
<lang arturo>print [sha1 "The quick brown fox jumped over the lazy dog's back"]</lang>
- Output:
9f2cbbcba105f1390db79a263af5bf9554f935a4
Astro
<lang python>import crypto { sha1 } let hash = sha1.hexdigest('Ars longa, vita brevis') print hash </lang>
AutoHotkey
Source: SHA-1 @github by jNizM <lang AutoHotkey>str := "Rosetta Code" MsgBox, % "String:`n" (str) "`n`nSHA:`n" SHA(str)
- SHA ===============================================================================
SHA(string, encoding = "utf-8") {
return CalcStringHash(string, 0x8004, encoding)
}
- CalcAddrHash ======================================================================
CalcAddrHash(addr, length, algid, byref hash = 0, byref hashlength = 0) {
static h := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"] static b := h.minIndex() o := "" if (DllCall("advapi32\CryptAcquireContext", "Ptr*", hProv, "Ptr", 0, "Ptr", 0, "UInt", 24, "UInt", 0xF0000000)) { if (DllCall("advapi32\CryptCreateHash", "Ptr", hProv, "UInt", algid, "UInt", 0, "UInt", 0, "Ptr*", hHash)) { if (DllCall("advapi32\CryptHashData", "Ptr", hHash, "Ptr", addr, "UInt", length, "UInt", 0)) { if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", 0, "UInt*", hashlength, "UInt", 0)) { VarSetCapacity(hash, hashlength, 0) if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", &hash, "UInt*", hashlength, "UInt", 0)) { loop, % hashlength { v := NumGet(hash, A_Index - 1, "UChar") o .= h[(v >> 4) + b] h[(v & 0xf) + b] } } } } DllCall("advapi32\CryptDestroyHash", "Ptr", hHash) } DllCall("advapi32\CryPtreleaseContext", "Ptr", hProv, "UInt", 0) } return o
}
- CalcStringHash ====================================================================
CalcStringHash(string, algid, encoding = "utf-8", byref hash = 0, byref hashlength = 0) {
chrlength := (encoding = "cp1200" || encoding = "utf-16") ? 2 : 1 length := (StrPut(string, encoding) - 1) * chrlength VarSetCapacity(data, length, 0) StrPut(string, &data, floor(length / chrlength), encoding) return CalcAddrHash(&data, length, algid, hash, hashlength)
}</lang>
- Output:
String: Rosetta Code SHA-1: 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
BBC BASIC
Library
<lang bbcbasic> PRINT FNsha1("Rosetta Code")
END DEF FNsha1(message$) LOCAL buflen%, buffer%, hprov%, hhash%, hash$, i% CALG_SHA1 = &8004 CRYPT_VERIFYCONTEXT = &F0000000 HP_HASHVAL = 2 PROV_RSA_FULL = 1 buflen% = 64 DIM buffer% LOCAL buflen%-1 SYS "CryptAcquireContext", ^hprov%, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT SYS "CryptCreateHash", hprov%, CALG_SHA1, 0, 0, ^hhash% SYS "CryptHashData", hhash%, message$, LEN(message$), 0 SYS "CryptGetHashParam", hhash%, HP_HASHVAL, buffer%, ^buflen%, 0 SYS "CryptDestroyHash", hhash% SYS "CryptReleaseContext", hprov% FOR i% = 0 TO buflen%-1 hash$ += RIGHT$("0" + STR$~buffer%?i%, 2) NEXT = hash$</lang>
- Output:
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
Native
<lang bbcbasic> *FLOAT64
PRINT FNsha1("Rosetta Code") END DEF FNsha1(message$) LOCAL a%, b%, c%, d%, e%, f%, i%, j%, k%, l%, t% LOCAL h0%, h1%, h2%, h3%, h4%, w%() REM Initialize variables: h0% = &67452301 h1% = &EFCDAB89 h2% = &98BADCFE h3% = &10325476 h4% = &C3D2E1F0 l% = LEN(message$)*8 REM Pre-processing: REM append the bit '1' to the message: message$ += CHR$&80 REM append k bits '0', where k is the minimum number >= 0 such that REM the resulting message length (in bits) is congruent to 448 (mod 512) WHILE (LEN(message$) MOD 64) <> 56 message$ += CHR$0 ENDWHILE REM append length of message (before pre-processing), in bits, as REM 64-bit big-endian integer FOR i% = 56 TO 0 STEP -8 message$ += CHR$(l% >>> i%) NEXT REM Process the message in successive 512-bit chunks: REM break message into 512-bit chunks, for each chunk REM break chunk into sixteen 32-bit big-endian words w[i], 0 <= i <= 15 DIM w%(79) FOR j% = 0 TO LEN(message$) DIV 64 - 1 FOR i% = 0 TO 15 w%(i%) = !(!^message$ + 64*j% + 4*i%) SWAP ?(^w%(i%)+0),?(^w%(i%)+3) SWAP ?(^w%(i%)+1),?(^w%(i%)+2) NEXT i% REM Extend the sixteen 32-bit words into eighty 32-bit words: FOR i% = 16 TO 79 w%(i%) = w%(i%-3) EOR w%(i%-8) EOR w%(i%-14) EOR w%(i%-16) w%(i%) = (w%(i%) << 1) OR (w%(i%) >>> 31) NEXT i% REM Initialize hash value for this chunk: a% = h0% b% = h1% c% = h2% d% = h3% e% = h4% REM Main loop: FOR i% = 0 TO 79 CASE TRUE OF WHEN 0 <= i% AND i% <= 19 f% = (b% AND c%) OR ((NOT b%) AND d%) k% = &5A827999 WHEN 20 <= i% AND i% <= 39 f% = b% EOR c% EOR d% k% = &6ED9EBA1 WHEN 40 <= i% AND i% <= 59 f% = (b% AND c%) OR (b% AND d%) OR (c% AND d%) k% = &8F1BBCDC WHEN 60 <= i% AND i% <= 79 f% = b% EOR c% EOR d% k% = &CA62C1D6 ENDCASE t% = FN32(((a% << 5) OR (a% >>> 27)) + f% + e% + k% + w%(i%)) e% = d% d% = c% c% = (b% << 30) OR (b% >>> 2) b% = a% a% = t% NEXT i% REM Add this chunk's hash to result so far: h0% = FN32(h0% + a%) h1% = FN32(h1% + b%) h2% = FN32(h2% + c%) h3% = FN32(h3% + d%) h4% = FN32(h4% + e%) NEXT j% = FNhex(h0%) + FNhex(h1%) + FNhex(h2%) + FNhex(h3%) + FNhex(h4%) DEF FNhex(A%) = RIGHT$("0000000"+STR$~A%,8) DEF FN32(n#) WHILE n# > &7FFFFFFF : n# -= 2^32 : ENDWHILE WHILE n# < &80000000 : n# += 2^32 : ENDWHILE = n#</lang>
- Output:
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
C
<lang c>#include <stdio.h>
- include <stdlib.h>
- include <string.h>
- include <openssl/sha.h>
int main() {
int i; unsigned char result[SHA_DIGEST_LENGTH]; const char *string = "Rosetta Code"; SHA1(string, strlen(string), result); for(i = 0; i < SHA_DIGEST_LENGTH; i++) printf("%02x%c", result[i], i < (SHA_DIGEST_LENGTH-1) ? ' ' : '\n'); return EXIT_SUCCESS;
}</lang>
C#
Tests the built-in SHA1CryptoServiceProvider: <lang csharp>using System; using System.Security.Cryptography; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace RosettaCode.SHA1 {
[TestClass] public class SHA1CryptoServiceProviderTest { [TestMethod] public void TestComputeHash() { var input = new UTF8Encoding().GetBytes("Rosetta Code"); var output = new SHA1CryptoServiceProvider().ComputeHash(input); Assert.AreEqual( "48-C9-8F-7E-5A-6E-73-6D-79-0A-B7-40-DF-C3-F5-1A-61-AB-E2-B5", BitConverter.ToString(output)); } }
}</lang>
C++
Compiling with g++ -lPocoCrypto shaexample.cpp -o shaexample
:
<lang cpp>#include <string>
- include <iostream>
- include "Poco/SHA1Engine.h"
- include "Poco/DigestStream.h"
using Poco::DigestEngine ; using Poco::SHA1Engine ; using Poco::DigestOutputStream ;
int main( ) {
std::string myphrase ( "Rosetta Code" ) ; SHA1Engine sha1 ; DigestOutputStream outstr( sha1 ) ; outstr << myphrase ; outstr.flush( ) ; //to pass everything to the digest engine const DigestEngine::Digest& digest = sha1.digest( ) ; std::cout << myphrase << " as a sha1 digest :" << DigestEngine::digestToHex( digest ) << " !" << std::endl ; return 0 ;
}</lang>
- Output:
Rosetta Code as a sha1 digest :48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 !
Caché ObjectScript
USER>set hash=$System.Encryption.SHA1Hash("Rosetta Code") USER>zzdump hash 0000: 48 C9 8F 7E 5A 6E 73 6D 79 0A B7 40 DF C3 F5 1A 0010: 61 AB E2 B5
Clojure
As Clojure is interoperable with Java the solution to this task would be a small modification to MD5, as with Java. (Replacing "MD5" with "SHA-1" as noted here.)
Common Lisp
This example uses the Ironclad cryptography library (available via Quicklisp as well). <lang lisp>;;; in addition to sha1, ironclad provides sha224, sha256, sha384, and sha512. (defun sha1-hash (data)
(let ((sha1 (ironclad:make-digest 'ironclad:sha1)) (bin-data (ironclad:ascii-string-to-byte-array data))) (ironclad:update-digest sha1 bin-data) (ironclad:byte-array-to-hex-string (ironclad:produce-digest sha1))))
</lang>
Crystal
<lang ruby>require "openssl" puts OpenSSL::Digest.new("sha1").update("Rosetta Code")</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
D
First: Use native 'std.digest.sha' library
<lang d>void main() {
import std.stdio, std.digest.sha;
writefln("%-(%02x%)", "Ars longa, vita brevis".sha1Of);
}</lang>
- Output:
e640d285242886eb96ab80cbf858389b3df52f43
Second: Re-implement SHA-1 in D <lang d>import std.stdio, std.string, std.conv, std.algorithm, std.format, std.array,
std.range, std.digest.sha;
int rol(int n, int b) {
return ((n << b) | (n >>> (32 - b))) & 0xffffffff;
}
int btoi(string bin) {
int total = 0; foreach (b; bin) { total *= 2; (b == '1') ? total += 1 : total; } return total;
}
string sha1(char[] intake) {
int h0 = 0x67452301; int h1 = 0xEFCDAB89; int h2 = 0x98BADCFE; int h3 = 0x10325476; int h4 = 0xC3D2E1F0;
auto bins = intake.map!(x => format("%08b", x.to!int)); int binsize = bins.join().length.to!int; string o = bins.join() ~ "1"; o ~= replicate("0", 448%512 - o.length.to!int%512) ~ format("%064b", binsize); auto binchunks = chunks(o, 512).array; foreach (chunk; binchunks) { string[] words = chunk.chunks(512/16).array .map!(x => "%032s".format(x)).array; foreach (i; iota(16, 80)) { int newWord = btoi(words[i-3]) ^ btoi(words[i-8]) ^ btoi(words[i-14]) ^ btoi(words[i-16]); newWord = rol(newWord, 1); words = words.array ~ "%032b".format(newWord); } int A = h0; int B = h1; int C = h2; int D = h3; int E = h4; foreach (i; iota(0, 80)) { int F = 0; int K = 0; if (i < 20) { F = D ^ (B & (C ^ D)); K = 0x5A827999; } else if (i < 40) { F = B ^ C ^ D; K = 0x6ED9EBA1; } else if (i < 60) { F = (B & C) | (B & D) | (C & D); K = 0x8F1BBCDC; } else if (i < 80) { F = B ^ C ^ D; K = 0xCA62C1D6; } int tempA = A; A = rol(A, 5) + F + E + K + btoi(words[i]) & 0xffffffff; E = D; D = C; C = rol(B,30); B = tempA; }
h0 = btoi("%032b".format(h0 + A).retro.array[0 .. 32].retro.to!string); h1 = btoi("%032b".format(h1 + B).retro.array[0 .. 32].retro.to!string); h2 = btoi("%032b".format(h2 + C).retro.array[0 .. 32].retro.to!string); h3 = btoi("%032b".format(h3 + D).retro.array[0 .. 32].retro.to!string); h4 = btoi("%032b".format(h4 + E).retro.array[0 .. 32].retro.to!string); } return "%08x%08x%08x%08x%08x".format(h0, h1, h2, h3, h4);
}
void main() {
writeln(sha1("Rosetta Code".dup));
}</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
DWScript
<lang delphi>PrintLn( HashSHA1.HashData('Rosetta code') );</lang>
- Output:
b18c883f4da750164b5af362ea9b9f27f90904b4
Erlang
- Output:
12> crypto:hash( sha, "A string" ). <<110,185,174,8,151,66,9,104,174,225,10,43,9,92,82,190,197,150,224,92>>
F#
<lang fsharp> let n = System.Security.Cryptography.SHA1.Create() Array.iter (printf "%x ") (n.ComputeHash "Rosetta Code"B) </lang>
- Output:
48 c9 8f 7e 5a 6e 73 6d 79 a b7 40 df c3 f5 1a 61 ab e2 b5
Factor
Factor provides sha1 in the checksums.sha vocabulary. In Factor, checksum-bytes returns a sequence of bytes; hex-string converts this sequence to a hexadecimal string.
IN: scratchpad USING: checksums checksums.sha ; IN: scratchpad "Rosetta Code" sha1 checksum-bytes hex-string . "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"
The implementation is at basis/checksums/sha/sha.factor.
Note: In recent factor builds (after June 2017, ie factor 0.98), checksums:hex-string has been moved to math.parser:hex-string>bytes
Fortran
Intel Fortran on Windows
Using Windows API. See CryptAcquireContext, CryptCreateHash, CryptHashData and CryptGetHashParam on MSDN.
<lang fortran>module sha1_mod
use kernel32 use advapi32 implicit none integer, parameter :: SHA1LEN = 20
contains
subroutine sha1hash(name, hash, dwStatus, filesize) implicit none character(*) :: name integer, parameter :: BUFLEN = 32768 integer(HANDLE) :: hFile, hProv, hHash integer(DWORD) :: dwStatus, nRead integer(BOOL) :: status integer(BYTE) :: buffer(BUFLEN) integer(BYTE) :: hash(SHA1LEN) integer(UINT64) :: filesize dwStatus = 0 filesize = 0 hFile = CreateFile(trim(name) // char(0), GENERIC_READ, FILE_SHARE_READ, NULL, & OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) if (hFile == INVALID_HANDLE_VALUE) then dwStatus = GetLastError() print *, "CreateFile failed." return end if if (CryptAcquireContext(hProv, NULL, NULL, PROV_RSA_FULL, & CRYPT_VERIFYCONTEXT) == FALSE) then dwStatus = GetLastError() print *, "CryptAcquireContext failed." goto 3 end if if (CryptCreateHash(hProv, CALG_SHA1, 0_ULONG_PTR, 0_DWORD, hHash) == FALSE) then dwStatus = GetLastError() print *, "CryptCreateHash failed." go to 2 end if do status = ReadFile(hFile, loc(buffer), BUFLEN, nRead, NULL) if (status == FALSE .or. nRead == 0) exit filesize = filesize + nRead if (CryptHashData(hHash, buffer, nRead, 0) == FALSE) then dwStatus = GetLastError() print *, "CryptHashData failed." go to 1 end if end do if (status == FALSE) then dwStatus = GetLastError() print *, "ReadFile failed." go to 1 end if nRead = SHA1LEN if (CryptGetHashParam(hHash, HP_HASHVAL, hash, nRead, 0) == FALSE) then dwStatus = GetLastError() print *, "CryptGetHashParam failed.", status, nRead, dwStatus end if 1 status = CryptDestroyHash(hHash) 2 status = CryptReleaseContext(hProv, 0) 3 status = CloseHandle(hFile) end subroutine
end module
program sha1
use sha1_mod implicit none integer :: n, m, i, j character(:), allocatable :: name integer(DWORD) :: dwStatus integer(BYTE) :: hash(SHA1LEN) integer(UINT64) :: filesize n = command_argument_count() do i = 1, n call get_command_argument(i, length=m) allocate(character(m) :: name) call get_command_argument(i, name) call sha1hash(name, hash, dwStatus, filesize) if (dwStatus == 0) then do j = 1, SHA1LEN write(*, "(Z2.2)", advance="NO") hash(j) end do write(*, "(' ',A,' (',G0,' bytes)')") name, filesize end if deallocate(name) end do
end program</lang>
FreeBASIC
<lang freebasic>' version 18-10-2016 ' started with SHA-1/FIPS-180-1 ' but used the BBC BASIC native version to finish. ' compile with: fbc -s console
Function SHA_1(test_str As String) As String
Dim As String message = test_str ' strings are passed as ByRef's
Dim As Long i, j Dim As UByte Ptr ww1 Dim As UInteger<32> Ptr ww4
Dim As ULongInt l = Len(message) ' set the first bit after the message to 1 message = message + Chr(1 Shl 7) ' add one char to the length Dim As ULong padding = 64 - ((l +1) Mod (512 \ 8)) ' 512 \ 8 = 64 char.
' check if we have enough room for inserting the length If padding < 8 Then padding = padding + 64
message = message + String(padding, Chr(0)) ' adjust length Dim As ULong l1 = Len(message) ' new length
l = l * 8 ' orignal length in bits ' create ubyte ptr to point to l ( = length in bits) Dim As UByte Ptr ub_ptr = Cast(UByte Ptr, @l)
For i = 0 To 7 'copy length of message to the last 8 bytes message[l1 -1 - i] = ub_ptr[i] Next
Dim As UInteger<32> A, B, C, D, E, k, temp, W(0 To 79) Dim As UInteger<32> H0 = &H67452301 Dim As UInteger<32> H1 = &HEFCDAB89 Dim As UInteger<32> H2 = &H98BADCFE Dim As UInteger<32> H3 = &H10325476 Dim As UInteger<32> H4 = &HC3D2E1F0
For j = 0 To (l1 -1) \ 64 ' split into block of 64 bytes ww1 = Cast(Ubyte Ptr, @message[j * 64]) ww4 = Cast(UInteger<32> Ptr, @message[j * 64])
For i = 0 To 60 Step 4 'little endian -> big endian Swap ww1[i ], ww1[i +3] Swap ww1[i +1], ww1[i +2] Next For i = 0 To 15 ' copy the 16 32bit block into the array W(i) = ww4[i] Next For i = 16 To 79 ' fill the rest of the array temp = W(i -3) Xor W(i -8) Xor W(i -14) Xor W(i -16) temp = temp Shl 1 + temp Shr 31 W(i) = temp Next
A = h0 : B = h1 : C = h2 : D = h3 : E = h4
For i = 0 To 79 Select Case As Const i Case 0 To 19 temp = (B And C) or ((Not B) And D) k = &H5A827999 Case 20 To 39 temp = B Xor C Xor D k = &H6ED9EBA1 Case 40 To 59 temp = (B And C) Or (B And D) Or (C And D) k = &H8F1BBCDC Case 60 To 79 temp = B Xor C Xor D k = &hCA62C1D6 End Select
temp = A Shl 5 + A Shr 27 + temp + E + k + W(i) E = D D = C C = (B Shl 30) or (B Shr 2) B = A A = temp Next h0 += A : h1 += B : h2 += C : h3 += D : h4 += E
Next Return Hex(h0, 8) + Hex(h1, 8) + Hex(h2, 8) + Hex(h3, 8) + Hex(h4, 8)
End Function
' ------=< MAIN >=------
Dim As String test = "Rosetta Code" Print test; " => "; SHA_1(test)
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</lang>
- Output:
Rosetta Code => 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
Genie
SHA-1, being overtaken, is not recommended but is supported in GLib checksum, ChecksumType.SHA1.
<lang genie>print Checksum.compute_for_string(ChecksumType.SHA1, "Rosetta code", -1)</lang>
(The -1 is NUL byte terminated string indicator for length)
See SHA-256#Genie.
Go
<lang go>package main
import (
"crypto/sha1" "fmt"
)
func main() {
h := sha1.New() h.Write([]byte("Rosetta Code")) fmt.Printf("%x\n", h.Sum(nil))
}</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Halon
<lang halon>$var = "Rosetta Code"; echo sha1($var);</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Haskell
<lang Haskell>module Digestor
where
import Data.Digest.Pure.SHA import qualified Data.ByteString.Lazy as B
convertString :: String -> B.ByteString convertString phrase = B.pack $ map ( fromIntegral . fromEnum ) phrase
convertToSHA1 :: String -> String convertToSHA1 word = showDigest $ sha1 $ convertString word
main = do
putStr "Rosetta Code SHA1-codiert: " putStrLn $ convertToSHA1 "Rosetta Code"
</lang>
- Output:
Rosetta Code SHA1-codiert: 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Haxe
<lang haxe>import haxe.crypto.Sha1;
class Main {
static function main() { var sha1 = Sha1.encode("Rosetta Code"); Sys.println(sha1); }
}</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
J
From J8 the ide/qt addon includes bindings to the Qt library function for a number of hash algorithms incluing SHA-1. Thus: <lang j> require '~addons/ide/qt/qt.ijs'
getsha1=: 'sha1'&gethash_jqtide_ getsha1 'Rosetta Code'
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</lang>
From J8.06, the sha family of hashes have builtin support.
<lang j> sha1=:128!:6
sha1'Rosetta Code'
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</lang>
A implementation of SHA-1 in J follows:
<lang J>pad=: ,1,(0#~512 | [: - 65 + #),(64#2)#:#
f=:4 :0
'B C D'=: _32 ]\ y if. x < 20 do. (B*C)+.D>B elseif. x < 40 do. B~:C~:D elseif. x < 60 do. (B*C)+.(B*D)+.C*D elseif. x < 80 do. B~:C~:D end.
)
K=: ((32#2) #: 16b5a827999 16b6ed9eba1 16b8f1bbcdc 16bca62c1d6) {~ <.@%&20
plus=:+&.((32#2)&#.)
H=: #: 16b67452301 16befcdab89 16b98badcfe 16b10325476 16bc3d2e1f0
process=:4 :0
W=. (, [: , 1 |."#. _3 _8 _14 _16 ~:/@:{ ])^:64 x ]\~ _32 'A B C D E'=. y=._32[\,y for_t. i.80 do. TEMP=. (5|.A) plus (t f B,C,D) plus E plus (W{~t) plus K t E=. D D=. C C=. 30 |. B B=. A A=. TEMP end. ,y plus A,B,C,D,:E
)
sha1=: [:> [: process&.>/ (<H) (,~ |.) _512<\ pad</lang>
Example use:
<lang J> text2bits=: (8#2) ,@:#: a. i. ]
bits2hex=: '0123456789abcdef' {~ _4 #.\ ,
bits2hex sha1 text2bits 'Rosetta Code'
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</lang>
Remember that SHA-1 is an obsolete standard (and if you *really* want high speed you'd probably be using ASICs rather than a general purpose computing platform).
Java
The solution to this task would be a small modification to MD5 (replacing "MD5" with "SHA-1" as noted here).
Jsish
<lang javascript>/* SHA-1 hash in Jsish */ var str = 'Rosetta code'; puts(Util.hash(str, {type:'sha1'}));
/*
!EXPECTSTART!
b18c883f4da750164b5af362ea9b9f27f90904b4
!EXPECTEND!
- /</lang>
- Output:
prompt$ jsish sha-1.jsi b18c883f4da750164b5af362ea9b9f27f90904b4 prompt$ jsish -u sha-1.jsi [PASS] sha-1.jsi
Julia
<lang julia>using Nettle
testdict = Dict("abc" => "a9993e364706816aba3e25717850c26c9cd0d89d",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" => "84983e441c3bd26ebaae4aa1f95129e5e54670f1", "a" ^ 1_000_000 => "34aa973cd4c4daa4f61eeb2bdbad27316534016f",)
for (text, expect) in testdict
digest = hexdigest("sha1", text) if length(text) > 50 text = text[1:50] * "..." end println("# $text\n -> digest: $digest\n -> expect: $expect")
end</lang>
- Output:
# abc -> digest: a9993e364706816aba3e25717850c26c9cd0d89d -> expect: a9993e364706816aba3e25717850c26c9cd0d89d # abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomn... -> digest: 84983e441c3bd26ebaae4aa1f95129e5e54670f1 -> expect: 84983e441c3bd26ebaae4aa1f95129e5e54670f1 # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... -> digest: 34aa973cd4c4daa4f61eeb2bdbad27316534016f -> expect: 34aa973cd4c4daa4f61eeb2bdbad27316534016f
Kotlin
<lang scala>// version 1.0.6
import java.security.MessageDigest
fun main(args: Array<String>) {
val text = "Rosetta Code" val bytes = text.toByteArray() val md = MessageDigest.getInstance("SHA-1") val digest = md.digest(bytes) for (byte in digest) print("%02x".format(byte)) println()
}</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Lasso
<lang Lasso>cipher_digest('Rosetta Code', -digest='SHA1',-hex=true)</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Liberty BASIC
<lang lb> '-------------------------------------------------------------------------------- ' FAST SHA1 CALCULATION BASED ON MS ADVAPI32.DLL BY CRYPTOMAN ' ' BASED ON SHA256 EXAMPLE BY RICHARD T. RUSSEL AUTHOR OF LBB ' ' http://lbb.conforums.com/ ' ' VERIFY CORRECTNESS BY http://www.fileformat.info/tool/hash.htm ' '--------------------------------------------------------------------------------
print sha1$("Rosetta Code") end
X$="1234567890ABCDEF"
dat$ = pack$(X$)
print "SPEED TEST" for i=1 to 20 t1=time$("ms") print sha1$(dat$) t2=time$("ms") print "calculated in ";t2-t1;" ms" next end
function sha1$(message$)
HP.HASHVAL = 2 CRYPT.NEWKEYSET = 48 PROV.RSA.AES = 24 buffer$ = space$(128)
PROVRSAFULL = 1 ALGCLASSHASH = 32768 ALGTYPEANY = 0 ALGSIDMD2 = 1 ALGSIDMD4 = 2 ALGSIDMD5 = 3 ALGSIDSHA1 = 4
ALGOSHA1 = ALGCLASSHASH OR ALGTYPEANY OR ALGSIDSHA1
struct temp, v as long open "ADVAPI32.DLL" for dll as #advapi32 calldll #advapi32, "CryptAcquireContextA", temp as struct, _ 0 as long, 0 as long, PROV.RSA.AES as long, _ 0 as long, re as long hprov = temp.v.struct calldll #advapi32, "CryptCreateHash", hprov as long, _ ALGOSHA1 as long, 0 as long, 0 as long, _ temp as struct, re as long hhash = temp.v.struct l = len(message$) calldll #advapi32, "CryptHashData", hhash as long, message$ as ptr, _ l as long, 0 as long, re as long temp.v.struct = len(buffer$) calldll #advapi32, "CryptGetHashParam", hhash as long, _ HP.HASHVAL as long, buffer$ as ptr, _ temp as struct, 0 as long, re as long calldll #advapi32, "CryptDestroyHash", hhash as long, re as long calldll #advapi32, "CryptReleaseContext", hprov as long, re as long close #advapi32 for i = 1 TO temp.v.struct sha1$ = sha1$ + right$("0" + dechex$(asc(mid$(buffer$,i))), 2) next
end function
function pack$(x$)
for i = 1 TO len(x$) step 2 pack$ = pack$ + chr$(hexdec(mid$(x$,i,2))) next
end function </lang>
- Output:
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
Lingo
<lang lingo>crypto = xtra("Crypto").new() put crypto.cx_sha1_string("Rosetta Code")</lang>
- Output:
-- "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"
LiveCode
<lang LiveCode>command shaRosettaCode
local shex, sha1 put sha1Digest("Rosetta Code") into sha1 get binaryDecode("H*",sha1,shex) put shex
end shaRosettaCode</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Lua
<lang Lua>#!/usr/bin/lua
local sha1 = require "sha1"
for i, str in ipairs{"Rosetta code", "Rosetta Code"} do
print(string.format("SHA-1(%q) = %s", str, sha1(str)))
end</lang>
- Output:
SHA-1("Rosetta code") = b18c883f4da750164b5af362ea9b9f27f90904b4 SHA-1("Rosetta Code") = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Mathematica
<lang>Hash["Rosetta code","SHA1","HexString"]</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
min
<lang min>"Rosetta Code" sha1 puts!</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
NetRexx
This solution is basically the same as that for MD5, substituting "SHA-1" for "MD5" as the algorithm to use in the MessageDigest instance. <lang NetRexx>/* NetRexx */ options replace format comments java crossref savelog symbols binary
import java.security.MessageDigest
SHA1('Rosetta Code', '48c98f7e5a6e736d790ab740dfc3f51a61abe2b5')
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method SHA1(messageText, verifyCheck) public static
algorithm = 'SHA-1' digestSum = getDigest(messageText, algorithm)
say '<Message>'messageText'</Message>' say Rexx('<'algorithm'>').right(12) || digestSum'</'algorithm'>' say Rexx('<Verify>').right(12) || verifyCheck'</Verify>' if digestSum == verifyCheck then say algorithm 'Confirmed' else say algorithm 'Failed'
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method getDigest(messageText = Rexx, algorithm = Rexx 'MD5', encoding = Rexx 'UTF-8', lowercase = boolean 1) public static returns Rexx
algorithm = algorithm.upper encoding = encoding.upper
message = String(messageText) messageBytes = byte[] digestBytes = byte[] digestSum = Rexx
do messageBytes = message.getBytes(encoding) md = MessageDigest.getInstance(algorithm) md.update(messageBytes) digestBytes = md.digest
loop b_ = 0 to digestBytes.length - 1 bb = Rexx(digestBytes[b_]).d2x(2) if lowercase then digestSum = digestSum || bb.lower else digestSum = digestSum || bb.upper end b_ catch ex = Exception ex.printStackTrace end return digestSum
</lang>
- Output:
<Message>Rosetta Code</Message> <SHA-1>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</SHA-1> <Verify>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</Verify> SHA-1 Confirmed
NewLISP
<lang NewLISP>;; using the crypto module from http://www.newlisp.org/code/modules/crypto.lsp.html
- (import native functions from the crypto library, provided by OpenSSL)
(module "crypto.lsp") (crypto:sha1 "Rosetta Code")</lang>
Nim
Compile with nim -d:ssl c sha1.nim
:
<lang nim>import strutils
const SHA1Len = 20
proc SHA1(d: cstring, n: culong, md: cstring = nil): cstring {.cdecl, dynlib: "libssl.so", importc.}
proc SHA1(s: string): string =
result = "" var s = SHA1(s.cstring, s.len.culong) for i in 0 .. < SHA1Len: result.add s[i].BiggestInt.toHex(2).toLower
echo SHA1("Rosetta Code")</lang>
Oberon-2
<lang oberon2> MODULE SHA1; IMPORT
Crypto:SHA1, Crypto:Utils, Strings, Out;
VAR
h: SHA1.Hash; str: ARRAY 128 OF CHAR;
BEGIN
h := SHA1.NewHash(); h.Initialize; str := "Rosetta Code"; h.Update(str,0,Strings.Length(str)); h.GetHash(str,0); Out.String("SHA1: ");Utils.PrintHex(str,0,h.size);Out.Ln
END SHA1. </lang>
- Output:
SHA1: 48C98F7E 5A6E736D 790AB740 DFC3F51A 61ABE2B5
OCaml
Using the library ocaml-sha
in the interactive loop:
<lang ocaml>$ ocaml -I +sha sha1.cma
Objective Caml version 3.12.1
- Sha1.to_hex (Sha1.string "Rosetta Code") ;;
- : string = "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"</lang>
Octave
Normally SHA-1 is available in the general package.
<lang octave>sprintf("%02x", SHA1(+"Rosetta Code"(:)))</lang>
- Output:
ans = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
PARI/GP
It works on Linux systems.
<lang parigp>sha1(s)=extern("echo \"Str(`echo -n '"Str(s)"'|sha1sum|cut -d' ' -f1`)\"")</lang>
The code above creates a new function sha1(s) which returns SHA-1 hash of item s.
- Output:
sha1("Rosetta Code") = "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5" sha1(1+2) = "77de68daecd823babbb58edb1c8e14d7106e83bb" ; sha(3)
Pascal
<lang pascal>program RosettaSha1; uses
sha1;
var
d: TSHA1Digest;
begin
d:=SHA1String('Rosetta Code'); WriteLn(SHA1Print(d));
end.</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Perl
<lang perl>use Digest::SHA qw(sha1_hex);
print sha1_hex('Rosetta Code'), "\n";</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
The same in OO manner <lang perl>use Digest::SHA;
my $sha1 = Digest::SHA->new(1); $sha1->add('Rosetta Code'); print $sha1->hexdigest, "\n";</lang>
Phix
<lang Phix>-- -- demo\rosetta\sha1.exw -- ===================== -- -- NB no longer considered secure. Non-optimised. -- constant m4 = allocate(4) -- scratch area, for uint32
function uint32(atom v)
poke4(m4,v) return peek4u(m4)
end function
function sq_uint32(sequence s)
for i=1 to length(s) do s[i] = uint32(s[i]) end for return s
end function
function dword(string msg, integer i) -- get dword as big-endian
return msg[i]*#1000000+msg[i+1]*#10000+msg[i+2]*#100+msg[i+3]
end function
function xor_all(sequence s) atom result = 0
for i=1 to length(s) do result = xor_bits(result, s[i]) end for result = uint32(result) return result
end function
function rol(atom word, integer bits) -- left rotate the bits of a 32-bit number by the specified number of bits
return uint32(word*power(2,bits))+floor(word/power(2,32-bits))
end function
function sha1(string msg) atom a,b,c,d,e,temp,k sequence w = repeat(0,80) atom h0 = 0x67452301,
h1 = 0xefcdab89, h2 = 0x98badcfe, h3 = 0x10325476, h4 = 0xc3d2e1f0
integer bits = length(msg)*8 msg &= #80 while mod(length(msg),64)!=56 do msg &= '\0' end while msg &= reverse(int_to_bytes(bits,8))
for chunk=1 to length(msg) by 64 do for i=1 to 16 do w[i] = dword(msg,chunk+(i-1)*4) end for for i=17 to 80 do w[i] = rol(xor_all({w[i-3],w[i-8],w[i-14],w[i-16]}),1) end for {a,b,c,d,e} = {h0,h1,h2,h3,h4} for i=1 to 80 do if i<=20 then temp = or_bits(and_bits(b,c),and_bits(not_bits(b),d)) k = #5A827999 elsif i<=40 then temp = xor_bits(xor_bits(b,c),d) k = #6ED9EBA1 elsif i<=60 then temp = or_bits(or_bits(and_bits(b,c),and_bits(b,d)),and_bits(c,d)) k = #8F1BBCDC else -- i<=80 temp = xor_bits(xor_bits(b,c),d) k = #CA62C1D6 end if {a,b,c,d,e} = {uint32(rol(a,5)+temp+e+k+w[i]),a,rol(b,30),c,d} end for {h0,h1,h2,h3,h4} = sq_uint32(sq_add({h0,h1,h2,h3,h4},{a,b,c,d,e})) end for sequence res = {h0, h1, h2, h3, h4} for i=1 to length(res) do res[i] = sprintf("%08X",res[i]) end for return join(res)
end function
?sha1("Rosetta Code")</lang>
- Output:
"48c98f7e 5a6e736d 790ab740 dfc3f51a 61abe2b5"
PHP
<lang php><?php $string = 'Rosetta Code'; echo sha1( $string ), "\n"; ?></lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
PicoLisp
Library and implementation. <lang PicoLisp>(de leftRotate (X C)
(| (mod32 (>> (- C) X)) (>> (- 32 C) X)) )
(de mod32 (N)
(& N `(hex "FFFFFFFF")) )
(de not32 (N)
(x| N `(hex "FFFFFFFF")) )
(de add32 @
(mod32 (pass +)) )
(de sha1 (Str)
(let Len (length Str) (setq Str (conc (need (- 8 (* 64 (/ (+ Len 1 8 63) 64)) ) (conc (mapcar char (chop Str)) (cons `(hex "80")) ) 0 ) (flip (make (setq Len (* 8 Len)) (do 8 (link (& Len 255)) (setq Len (>> 8 Len )) ) ) ) ) ) ) (let (H0 `(hex "67452301") H1 `(hex "EFCDAB89") H2 `(hex "98BADCFE") H3 `(hex "10325476") H4 `(hex "C3D2E1F0") ) (while Str (let (A H0 B H1 C H2 D H3 E H4 W (conc (make (do 16 (link (apply | (mapcar >> (-24 -16 -8 0) (cut 4 'Str)) ) ) ) ) (need 64 0) ) ) (for (I 17 (>= 80 I) (inc I)) (set (nth W I) (leftRotate (x| (get W (- I 3)) (get W (- I 8)) (get W (- I 14)) (get W (- I 16)) ) 1 ) ) ) (use (Tmp F K) (for I 80 (cond ((>= 20 I) (setq F (| (& B C) (& (not32 B) D)) K `(hex "5A827999") ) ) ((>= 40 I) (setq F (x| B C D) K `(hex "6ED9EBA1") ) ) ((>= 60 I) (setq F (| (& B C) (& B D) (& C D)) K `(hex "8F1BBCDC") ) ) (T (setq F (x| B C D) K `(hex "CA62C1D6") ) ) ) (setq Tmp (add32 (leftRotate A 5) F E K (get W I) ) E D D C C (leftRotate B 30) B A A Tmp ) ) ) (setq H0 (add32 H0 A) H1 (add32 H1 B) H2 (add32 H2 C) H3 (add32 H3 D) H4 (add32 H4 E) ) ) ) (mapcan '((N) (flip (make (do 4 (link (& 255 N)) (setq N (>> 8 N)) ) ) ) ) (list H0 H1 H2 H3 H4) ) ) )
(let Str "Rosetta Code"
(println (pack (mapcar '((B) (pad 2 (hex B))) (sha1 Str) ) ) ) (println (pack (mapcar '((B) (pad 2 (hex B))) (native "libcrypto.so" "SHA1" '(B . 20) Str (length Str) '(NIL (20)) ) ) ) ) )
(bye)</lang>
Pike
<lang Pike> string input = "Rosetta Code"; string out = Crypto.SHA1.hash(input); write( String.string2hex(out) +"\n"); </lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
PowerShell
<lang PowerShell> Function Calculate-SHA1( $String ){
$Enc = [system.Text.Encoding]::UTF8 $Data = $enc.GetBytes($String)
# Create a New SHA1 Crypto Provider $Sha = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider
# Now hash and display results $Result = $sha.ComputeHash($Data) [System.Convert]::ToBase64String($Result)
} </lang> taken from Stackoverflow with a little modification
PureBasic
PB Version 5.40 <lang purebasic>a$="Rosetta Code"
UseSHA1Fingerprint() : b$=StringFingerprint(a$, #PB_Cipher_SHA1)
OpenConsole() Print("[SHA1] Text: "+a$+" ==> "+b$) Input()</lang>
- Output:
[SHA1] Text: Rosetta Code ==> 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Python
<lang python>import hashlib h = hashlib.sha1() h.update(bytes("Ars longa, vita brevis", encoding="ASCII")) h.hexdigest()
- "e640d285242886eb96ab80cbf858389b3df52f43"</lang>
R
<lang rsplus> library(digest)
input <- "Rosetta Code" cat(digest(input, algo = "sha1", serialize = FALSE), "\n") </lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Racket
With the built-in file/sha1 library:
<lang racket>
- lang racket
(require file/sha1) (sha1 (open-input-string "Rosetta Code")) </lang>
With the faster openssl/sha1 library (requires OpenSSL to be installed):
<lang racket>
- lang racket
(require openssl/sha1) (sha1 (open-input-string "Rosetta Code")) </lang>
Raku
(formerly Perl 6)
Pure Raku
A pure Raku implementation that closely follows the description of SHA-1 in FIPS 180-1. Slow.
<lang perl6>sub postfix:<mod2³²> { $^x % 2**32 } sub infix:<⊕> { ($^x + $^y)mod2³² } sub S { ($^x +< $^n)mod2³² +| ($x +> (32-$n)) }
my \f = -> \B,\C,\D { (B +& C) +| ((+^B)mod2³² +& D) },
-> \B,\C,\D { B +^ C +^ D }, -> \B,\C,\D { (B +& C) +| (B +& D) +| (C +& D) }, -> \B,\C,\D { B +^ C +^ D };
my \K = 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6;
sub sha1-pad(Blob $msg) {
my \bits = 8 * $msg.elems; my @padded = flat $msg.list, 0x80, 0x00 xx (-($msg.elems + 1 + 8) % 64); flat @padded.map({ :256[$^a,$^b,$^c,$^d] }), (bits +> 32)mod2³², (bits)mod2³²;
}
sub sha1-block(@H, @M is copy) {
@M.push: S(1, [+^] @M[$_ «-« <3 8 14 16>] ) for 16 .. 79;
my ($A,$B,$C,$D,$E) = @H; for 0..79 -> \t { ($A, $B, $C, $D, $E) = S(5,$A) ⊕ f[t div 20]($B,$C,$D) ⊕ $E ⊕ @M[t] ⊕ K[t div 20], $A, S(30,$B), $C, $D; } @H »⊕=« ($A,$B,$C,$D,$E);
}
sub sha1(Blob $msg) returns Blob {
my @M = sha1-pad($msg); my @H = 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0; sha1-block(@H,@M[$_..$_+15]) for 0, 16...^ +@M; Blob.new: flat map { reverse .polymod(256 xx 3) }, @H;
}
say sha1(.encode('ascii')), " $_"
for 'abc', 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'Rosetta Code', 'Ars longa, vita brevis';</lang>
- Output:
Buf:0x<a9 99 3e 36 47 06 81 6a ba 3e 25 71 78 50 c2 6c 9c d0 d8 9d> abc Buf:0x<84 98 3e 44 1c 3b d2 6e ba ae 4a a1 f9 51 29 e5 e5 46 70 f1> abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq Buf:0x<48 c9 8f 7e 5a 6e 73 6d 79 0a b7 40 df c3 f5 1a 61 ab e2 b5> Rosetta Code Buf:0x<e6 40 d2 85 24 28 86 eb 96 ab 80 cb f8 58 38 9b 3d f5 2f 43> Ars longa, vita brevis
Library based implementation
Quite speedy. <lang perl6>use Digest::SHA1::Native;
- use sha1-hex() if you want a hex string
say sha1($_), " $_" for
'abc', 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'Rosetta Code', 'Ars longa, vita brevis'
- </lang>
- Output:
Blob:0x<A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D> abc Blob:0x<84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1> abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq Blob:0x<48 C9 8F 7E 5A 6E 73 6D 79 0A B7 40 DF C3 F5 1A 61 AB E2 B5> Rosetta Code Blob:0x<E6 40 D2 85 24 28 86 EB 96 AB 80 CB F8 58 38 9B 3D F5 2F 43> Ars longa, vita brevis
Ring
<lang ring>
- Project : SHA-1
load "stdlib.ring" str = "Rosetta Code" see "String: " + str + nl see "SHA-1: " see sha1(str) + nl </lang> Output:
String: Rosetta Code SHA-1: 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Ruby
These programs print the SHA-1 of 'Rosetta Code', which is 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5.
First: Use 'digest' from Ruby's standard library. <lang ruby>require 'digest' puts Digest::SHA1.hexdigest('Rosetta Code')</lang>
Second: Use 'openssl' from Ruby's standard library.
<lang ruby>require 'openssl' puts OpenSSL::Digest::SHA1.hexdigest('Rosetta Code')</lang>
Third: Reimplement SHA-1 in Ruby. <lang ruby>require 'stringio'
- Calculates SHA-1 message digest of _string_. Returns binary digest.
- For hexadecimal digest, use +*sha1(string).unpack('H*')+.
- --
- This is a simple, pure-Ruby implementation of SHA-1, following
- the algorithm in FIPS 180-1.
- ++
def sha1(string)
# functions and constants mask = 0xffffffff s = proc{|n, x| ((x << n) & mask) | (x >> (32 - n))} f = [ proc {|b, c, d| (b & c) | (b.^(mask) & d)}, proc {|b, c, d| b ^ c ^ d}, proc {|b, c, d| (b & c) | (b & d) | (c & d)}, proc {|b, c, d| b ^ c ^ d}, ].freeze k = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6].freeze # initial hash h = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0] bit_len = string.size << 3 string += "\x80" while (string.size % 64) != 56 string += "\0" end string = string.force_encoding('ascii-8bit') + [bit_len >> 32, bit_len & mask].pack("N2") if string.size % 64 != 0 fail "failed to pad to correct length" end io = StringIO.new(string) block = "" while io.read(64, block) w = block.unpack("N16") # Process block. (16..79).each {|t| w[t] = s[1, w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16]]} a, b, c, d, e = h t = 0 4.times do |i| 20.times do temp = (s[5, a] + f[i][b, c, d] + e + w[t] + k[i]) & mask a, b, c, d, e = temp, a, s[30, b], c, d t += 1 end end [a,b,c,d,e].each_with_index {|x,i| h[i] = (h[i] + x) & mask} end h.pack("N5")
end
if __FILE__ == $0
# Print some example SHA-1 digests. # FIPS 180-1 has correct digests for 'abc' and 'abc...opq'. [ 'abc', 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'Rosetta Code', ].each {|s| printf("%s:\n %s\n", s, *sha1(s).unpack('H*'))}
end</lang>
- Output:
abc: a9993e364706816aba3e25717850c26c9cd0d89d abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq: 84983e441c3bd26ebaae4aa1f95129e5e54670f1 Rosetta Code: 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Rust
Using sha1 crate: https://docs.rs/sha1/0.6.0/sha1/ <lang Rust>use sha1::Sha1;
fn main() {
let mut hash_msg = Sha1::new(); hash_msg.update(b"Rosetta Code"); println!("{}", hash_msg.digest().to_string());
} </lang> Output
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
S-lang
Support for MD5 and SHA-1 are included in the standard "chksum" library:
<lang S-lang>require("chksum"); print(sha1sum("Rosetta Code"));</lang>
- Output:
"48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"
Scala
The solution to this task would be a small modification to MD5 (replacing "MD5" with "SHA-1" as noted here).
<lang scala> import java.nio._
case class Hash(message: List[Byte]) {
val defaultHashes = List(0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0) val hash = { val padded = generatePadding(message) val chunks: List[List[Byte]] = messageToChunks(padded) toHashForm(hashesFromChunks(chunks)) }
def generatePadding(message: List[Byte]): List[Byte] = { val finalPadding = BigInt(message.length * 8).toByteArray match { case x => List.fill(8 - x.length)(0.toByte) ++ x } val padding = (message.length + 1) % 64 match { case l if l < 56 => message ::: 0x80.toByte :: List.fill(56 - l)(0.toByte) case l => message ::: 0x80.toByte :: List.fill((64 - l) + 56 + 1)(0.toByte) } padding ::: finalPadding }
def toBigEndian(bytes: List[Byte]) = ByteBuffer.wrap(bytes.toArray).getInt
def messageToChunks(message: List[Byte]) = message.grouped(64).toList
def chunkToWords(chunk: List[Byte]) = chunk.grouped(4).map(toBigEndian).toList
def extendWords(words: List[Int]): List[Int] = words.length match { case i if i < 80 => extendWords(words :+ Integer.rotateLeft( (words(i - 3) ^ words(i - 8) ^ words(i - 14) ^ words(i - 16)), 1)) case _ => words }
def generateFK(i: Int, b: Int, c: Int, d: Int) = i match { case i if i < 20 => (b & c | ~b & d, 0x5A827999) case i if i < 40 => (b ^ c ^ d, 0x6ED9EBA1) case i if i < 60 => (b & c | b & d | c & d, 0x8F1BBCDC) case i if i < 80 => (b ^ c ^ d, 0xCA62C1D6) }
def generateHash(words: List[Int], prevHash: List[Int]): List[Int] = { def generateHash(i: Int, currentHashes: List[Int]): List[Int] = i match { case i if i < 80 => currentHashes match { case a :: b :: c :: d :: e :: Nil => { val (f, k) = generateFK(i, b, c, d) val x = Integer.rotateLeft(a, 5) + f + e + k + words(i) val t = Integer.rotateLeft(b, 30) generateHash(i + 1, x :: a :: t :: c :: d :: Nil) } } case _ => currentHashes } addHashes(prevHash, generateHash(0, prevHash)) }
def addHashes(xs: List[Int], ys: List[Int]) = (xs, ys).zipped.map(_ + _)
def hashesFromChunks(chunks: List[List[Byte]], remainingHash: List[Int] = defaultHashes): List[Int] = chunks match { case Nil => remainingHash case x :: xs => { val words = extendWords(chunkToWords(x)) val newHash = generateHash(words, remainingHash) hashesFromChunks(xs, newHash) } }
def toHashForm(hashes: List[Int]) = hashes.map(b => ByteBuffer.allocate(4) .order(ByteOrder.BIG_ENDIAN).putInt(b).array.toList) .map(bytesToHex).mkString
def bytesToHex(bytes: List[Byte]) = (for (byte <- bytes) yield (Character.forDigit((byte >> 4) & 0xF, 16) :: Character.forDigit((byte & 0xF), 16) :: Nil).mkString).mkString
}
object Hash extends App {
def hash(message: String) = new Hash(message.getBytes.toList).hash
println(hash("Rosetta Code"))
} </lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Scheme
<lang scheme>
- band - binary AND operation
- bor - binary OR operation
- bxor - binary XOR operation
- >>, << - binary shift operations
- runes->string - convert byte list to string /(runes->string '(65 66 67 65)) => "ABCA"/
(define (sha1-padding-size n)
(let ((x (mod (- 56 (rem n 64)) 64))) (if (= x 0) 64 x)))
(define (sha1-pad-message message)
(let*((message-len (string-length message)) (message-len-in-bits (* message-len 8)) (buffer-len (+ message-len 8 (sha1-padding-size message-len))) (message (string-append message (runes->string '(#b10000000)))) (zeroes-len (- buffer-len message-len 1 4)) ; for ending length encoded value (message (string-append message (make-string zeroes-len 0))) (message (string-append message (runes->string (list (band (>> message-len-in-bits 24) #xFF) (band (>> message-len-in-bits 16) #xFF) (band (>> message-len-in-bits 8) #xFF) (band (>> message-len-in-bits 0) #xFF))))))
- (print "message-len
- " message-len)
- (print "message-len-in-bits
- " message-len-in-bits)
- (print "buffer-len
- " buffer-len)
- (print "zeroes-len
- " zeroes-len)
- (print "message
- " message)
- (print "length(message)
- " (string-length message))
message))
(define XOR (lambda args (fold bxor 0 args))) ; bxor more than 2 arguments (define OR (lambda args (fold bor 0 args))) ; bor more than 2 arguments (define NOT (lambda (arg) (bxor arg #xFFFFFFFF))) ; binary not operation
- to 32-bit number
(define (->32 i)
(band i #xFFFFFFFF))
- binary cycle rotate left
(define (rol bits x)
(->32 (bor (<< x bits) (>> x (- 32 bits)))))
(define (word->list x)
(list (band (>> x 24) #xFF) (band (>> x 16) #xFF) (band (>> x 8) #xFF) (band (>> x 0) #xFF)))
(define (message->words message)
(let cycle ((W (let loop ((t (iota 0 1 16))) (if (null? t) null (let*((p (* (car t) 4))) (cons (OR (<< (string-ref message (+ p 0)) 24) (<< (string-ref message (+ p 1)) 16) (<< (string-ref message (+ p 2)) 8) (<< (string-ref message (+ p 3)) 0)) (loop (cdr t))))))) (t 16)) (if (eq? t 80) W (cycle (append W (list (XOR (rol 1 (list-ref W (- t 3))) (rol 1 (list-ref W (- t 8))) (rol 1 (list-ref W (- t 14))) (rol 1 (list-ref W (- t 16)))))) (+ t 1)))))
(define (sha1:digest message)
(let*((h0 #x67452301) (h1 #xEFCDAB89) (h2 #x98BADCFE) (h3 #x10325476) (h4 #xC3D2E1F0) (K '(#x5A827999 #x6ED9EBA1 #x8F1BBCDC #xCA62C1D6)) (padded-message (sha1-pad-message message)) (n (/ (string-length padded-message) 64)))
(let main ((i 0) (A h0) (B h1) (C h2) (D h3) (E h4)) (if (= i n) (fold append null (list (word->list A) (word->list B) (word->list C) (word->list D) (word->list E))) (let*((message (substring padded-message (* i 64) (+ (* i 64) 64))) (W (message->words message))) (let*((a b c d e ; round 1 (let loop ((a A) (b B) (c C) (d D) (e E) (t 0)) (if (< t 20) (loop (->32 (+ (rol 5 a) (OR (band b c) (band (NOT b) d)) e (list-ref W t) (list-ref K 0))) a (rol 30 b) c d (+ t 1)) (values a b c d e)))) (a b c d e ; round 2 (let loop ((a a) (b b) (c c) (d d) (e e) (t 20)) (if (< t 40) (loop (->32 (+ (rol 5 a) (XOR b c d) e (list-ref W t) (list-ref K 1))) a (rol 30 b) c d (+ t 1)) (values a b c d e)))) (a b c d e ; round 3 (let loop ((a a) (b b) (c c) (d d) (e e) (t 40)) (if (< t 60) (loop (->32 (+ (rol 5 a) (OR (band b c) (band b d) (band c d)) e (list-ref W t) (list-ref K 2))) a (rol 30 b) c d (+ t 1)) (values a b c d e)))) (a b c d e ; round 4 (let loop ((a a) (b b) (c c) (d d) (e e) (t 60)) (if (< t 80) (loop (->32 (+ (rol 5 a) (XOR b c d) e (list-ref W t) (list-ref K 3))) a (rol 30 b) c d (+ t 1)) (values a b c d e))))) (main (+ i 1) (->32 (+ A a)) (->32 (+ B b)) (->32 (+ C c)) (->32 (+ D d)) (->32 (+ E e)))))))))
</lang>
- Output:
<lang scheme> (define (->string value)
(runes->string (let ((L "0123456789abcdef")) (let loop ((v value)) (if (null? v) null (cons (string-ref L (>> (car v) 4)) (cons (string-ref L (band (car v) #xF)) (loop (cdr v)))))))))
(print (->string (sha1:digest "Rosetta Code"))) > 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 (print (->string (sha1:digest ""))) > da39a3ee5e6b4b0d3255bfef95601890afd80709 </lang>
Seed7
<lang seed7>$ include "seed7_05.s7i";
include "msgdigest.s7i";
const proc: main is func
begin writeln(hex(sha1("Rosetta Code"))); end func;</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Sidef
<lang ruby>var sha = frequire('Digest::SHA'); say sha.sha1_hex('Rosetta Code');</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Smalltalk
<lang smalltalk>PackageLoader fileInPackage: 'Digest'. (SHA1 hexDigestOf: 'Rosetta Code') displayNl.</lang>
<lang smalltalk>(SHA1Stream hashValueOf:'Rosetta Code')</lang>
Tcl
<lang tcl>package require sha1 puts [sha1::sha1 "Rosetta Code"]</lang>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
It should be noted that the sha1
package is actually a façade that uses an efficient implementation in C if one is available, or a pure Tcl version otherwise.
UNIX Shell
<lang bash>$ echo -n 'ASCII string' | sha1 9e9aeefe5563845ec5c42c5630842048c0fc261b</lang>
<lang bash>$ echo -n 'ASCII string' | openssl sha1 | sed 's/.*= //' 9e9aeefe5563845ec5c42c5630842048c0fc261b</lang>
zkl
Using zklMsgHash so. Can return the hash as a string of hex digits or bytes, can hash the hash N times. <lang zkl>$ zkl // run the REPL zkl: var MsgHash=Import("zklMsgHash") MsgHash zkl: MsgHash.SHA1("Rosetta Code") 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
zkl: var hash=MsgHash.SHA1("Rosetta Code",1,False) // hash once, return hash as bytes Data(20) zkl: hash.bytes() L(72,201,143,126,90,110,115,109,121,10,183,64,223,195,245,26,97,171,226,181) zkl: hash.bytes().apply("toString",16).concat() 48c98f7e5a6e736d79ab740dfc3f51a61abe2b5
zkl: MsgHash.SHA1("a"*1000,1000); // hash 1000 a's 1000 times 34aa973cd4c4daa4f61eeb2bdbad27316534016f</lang>
- Programming Tasks
- Solutions by Programming Task
- Checksums
- AArch64 Assembly
- Ada
- ARM Assembly
- Arturo
- Astro
- AutoHotkey
- BBC BASIC
- C
- OpenSSL
- C sharp
- C++
- Poco
- Caché ObjectScript
- Clojure
- Common Lisp
- Ironclad
- Crystal
- D
- DWScript
- Erlang
- F Sharp
- Factor
- Fortran
- FreeBASIC
- Genie
- Go
- Halon
- Haskell
- Haxe
- J
- Java
- Jsish
- Julia
- Kotlin
- Lasso
- Liberty BASIC
- Lingo
- Crypto Xtra
- LiveCode
- Lua
- Sha1
- Mathematica
- Min
- NetRexx
- NewLISP
- Nim
- Oberon-2
- Crypto
- OCaml
- Octave
- PARI/GP
- Pascal
- Perl
- Phix
- PHP
- PicoLisp
- Pike
- PowerShell
- PureBasic
- Python
- R
- Racket
- Raku
- Ring
- Ruby
- Rust
- S-lang
- Scala
- Scheme
- Seed7
- Sidef
- Smalltalk
- Tcl
- Tcllib
- UNIX Shell
- Zkl
- Lilypond/Omit
- TUSCRIPT/Omit