SHA-1: Difference between revisions
m →{{header|Wren}}: Minor tidy |
|||
(169 intermediate revisions by 86 users not shown) | |||
Line 1: | Line 1: | ||
{{task}} [[Category:Checksums]] |
{{task}} [[Category:Checksums]] |
||
'''SHA-1''' or '''SHA1''' is a one-way hash function; |
|||
'''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. |
|||
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, [ |
A US government standard, [[SHA-1/FIPS-180-1|FIPS 180-1]], defines SHA-1. |
||
Find the SHA-1 message digest for a string of [[octet]]s. You may either call a SHA-1 library, or implement SHA-1 in your language. Both approaches interest Rosetta Code. |
Find the SHA-1 message digest for a string of [[octet]]s. You may either call a SHA-1 library, or implement SHA-1 in your language. Both approaches interest Rosetta Code. |
||
{{alertbox|lightgray|'''Warning:''' SHA-1 has [https://en.wikinews.org/wiki/Chinese_researchers_crack_major_U.S._government_algorithm_used_in_digital_signatures known weaknesses]. Theoretical attacks may find a collision after [http://lwn.net/Articles/337745/ 2<sup>52</sup> operations], or perhaps fewer. |
{{alertbox|lightgray|'''Warning:''' SHA-1 has [https://en.wikinews.org/wiki/Chinese_researchers_crack_major_U.S._government_algorithm_used_in_digital_signatures known weaknesses]. Theoretical attacks may find a collision after [http://lwn.net/Articles/337745/ 2<sup>52</sup> operations], or perhaps fewer. |
||
This is much faster than a brute force attack of 2<sup>80</sup> operations. USgovernment [http://csrc.nist.gov/groups/ST/hash/statement.html deprecated SHA-1]. |
|||
For production-grade cryptography, users may consider a stronger alternative, such as SHA-256 (from the SHA-2 family) or the upcoming SHA-3.}} |
|||
=={{header|AArch64 Assembly}}== |
|||
{{works with|as|Raspberry Pi 3B version Buster 64 bits}} |
|||
<syntaxhighlight 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" |
|||
</syntaxhighlight> |
|||
{{Output}} |
|||
<pre> |
|||
Rosetta Code => 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5 |
|||
Program End ok. |
|||
</pre> |
|||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
{{works with|GNAT}} |
{{works with|GNAT}} |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; |
||
with GNAT.SHA1; |
with GNAT.SHA1; |
||
Line 18: | Line 416: | ||
Ada.Text_IO.Put_Line ("SHA1 (""Rosetta Code"") = " & |
Ada.Text_IO.Put_Line ("SHA1 (""Rosetta Code"") = " & |
||
GNAT.SHA1.Digest ("Rosetta Code")); |
GNAT.SHA1.Digest ("Rosetta Code")); |
||
end Main;</ |
end Main;</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre>SHA1 ("Rosetta Code") = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
<pre>SHA1 ("Rosetta Code") = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
||
=={{header|ARM Assembly}}== |
|||
{{works with|as|Raspberry Pi}} |
|||
<B>with openssl library </B> |
|||
<syntaxhighlight 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" |
|||
</syntaxhighlight> |
|||
<B>with only instructions assembly ARM</B> |
|||
<syntaxhighlight lang="text"> |
|||
/* 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" |
|||
</syntaxhighlight> |
|||
{{Output}} |
|||
<pre> |
|||
Rosetta Code => 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5 |
|||
Program End ok. |
|||
</pre> |
|||
=={{header|Arturo}}== |
|||
<syntaxhighlight lang="rebol">print digest.sha "The quick brown fox jumped over the lazy dog's back"</syntaxhighlight> |
|||
{{out}} |
|||
<pre>9f2cbbcba105f1390db79a263af5bf9554f935a4</pre> |
|||
=={{header|Astro}}== |
|||
<syntaxhighlight lang="python">import crypto { sha1 } |
|||
let hash = sha1.hexdigest('Ars longa, vita brevis') |
|||
print hash |
|||
</syntaxhighlight> |
|||
=={{header|AutoHotkey}}== |
|||
Source: [https://github.com/jNizM/AutoHotkey_Scripts/tree/master/Functions/Checksums SHA-1 @github] by jNizM |
|||
<syntaxhighlight 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) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>String: Rosetta Code |
|||
SHA-1: 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5</pre> |
|||
=={{header|BBC BASIC}}== |
|||
===Library=== |
|||
{{works with|BBC BASIC for Windows}} |
|||
<syntaxhighlight 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$</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5 |
|||
</pre> |
|||
===Native=== |
|||
{{works with|BBC BASIC for Windows}} |
|||
<syntaxhighlight 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#</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5 |
|||
</pre> |
|||
=={{header|C}}== |
|||
{{libheader|OpenSSL}} |
|||
<syntaxhighlight 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; |
|||
}</syntaxhighlight> |
|||
=={{header|C sharp}}== |
=={{header|C sharp}}== |
||
Tests the built-in SHA1CryptoServiceProvider: |
Tests the built-in SHA1CryptoServiceProvider: |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Security.Cryptography; |
using System.Security.Cryptography; |
||
using System.Text; |
using System.Text; |
||
Line 45: | Line 1,134: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
|||
{{libheader|Poco}} |
|||
Compiling with <code>g++ -lPocoCrypto shaexample.cpp -o shaexample</code>: |
|||
<syntaxhighlight 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 ; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Rosetta Code as a sha1 digest :48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 !</pre> |
|||
===Without external libraries=== |
|||
<syntaxhighlight lang="c++"> |
|||
#include <bit> |
|||
#include <cstdint> |
|||
#include <iomanip> |
|||
#include <iostream> |
|||
#include <sstream> |
|||
#include <string> |
|||
#include <vector> |
|||
class SHA1 { |
|||
public: |
|||
std::string message_digest(const std::string& message) { |
|||
std::vector<uint32_t> state = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }; |
|||
const std::vector<int8_t> bytes = add_padding(message); |
|||
for ( uint64_t i = 0; i < bytes.size() / BLOCK_LENGTH; ++i ) { |
|||
std::vector<uint32_t> values(80, 0); |
|||
for ( uint32_t j = 0; j < BLOCK_LENGTH; ++j ) { |
|||
values[j / 4] |= ( bytes[i * BLOCK_LENGTH + j] & 0xff ) << ( ( 3 - j % 4 ) * 8 ); |
|||
} |
|||
for ( uint32_t j = 16; j < 80; ++j ) { |
|||
uint32_t value = values[j - 3] ^ values[j - 8] ^ values[j - 14] ^ values[j - 16]; |
|||
values[j] = std::rotl(value, 1); |
|||
} |
|||
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4]; |
|||
uint32_t f = 0, k = 0; |
|||
for ( uint32_t j = 0; j < 80; ++j ) { |
|||
switch ( j / 20 ) { |
|||
case 0 : { f = ( b & c ) | ( ~b & d ); k = 0x5a827999; break; } |
|||
case 1 : { f = b ^ c ^ d; k = 0x6ed9eba1; break; } |
|||
case 2 : { f = ( b & c ) | ( b & d ) | ( c & d ); k = 0x8f1bbcdc; break; } |
|||
case 3 : { f = b ^ c ^ d; k = 0xca62c1d6; break; } |
|||
} |
|||
uint32_t temp = std::rotl(a, 5) + f + e + k + values[j]; |
|||
e = d; d = c; c = std::rotl(b, 30); b = a; a = temp; |
|||
} |
|||
state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; |
|||
} |
|||
std::stringstream stream; |
|||
for ( uint32_t i = 0; i < 20; ++i ) { |
|||
int8_t byte_value = static_cast<int8_t>(state[i / 4] >> ( 24 - ( i % 4 ) * 8)); |
|||
stream << std::setfill('0') << std::setw(2) << std::hex << ( byte_value & 0xff ); |
|||
} |
|||
return stream.str(); |
|||
} |
|||
private: |
|||
std::vector<int8_t> add_padding(const std::string& message) { |
|||
std::vector<int8_t> bytes(message.begin(), message.end()); |
|||
bytes.emplace_back(static_cast<uint8_t>(0x80)); |
|||
uint32_t padding = BLOCK_LENGTH - ( bytes.size() % BLOCK_LENGTH ); |
|||
if ( padding < 8 ) { |
|||
padding += BLOCK_LENGTH; |
|||
} |
|||
bytes.resize(bytes.size() + padding - 8, static_cast<int8_t>(0x0)); |
|||
const uint64_t bit_length = 8 * message.length(); |
|||
for ( int32_t i = 7; i >= 0; --i ) { |
|||
bytes.emplace_back(static_cast<int8_t>(bit_length >> ( 8 * i ))); |
|||
} |
|||
return bytes; |
|||
} |
|||
const uint32_t BLOCK_LENGTH = 64; |
|||
}; |
|||
int main() { |
|||
SHA1 sha1; |
|||
std::cout << sha1.message_digest("Rosetta Code") << std::endl; |
|||
} |
|||
</syntaxhighlight> |
|||
{{ out }} |
|||
<pre> |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Caché ObjectScript}}== |
|||
<pre>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</pre> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
As Clojure is interoperable with Java the solution to this task would be a small modification to [[MD5#Clojure|MD5]], as with Java. (Replacing "MD5" with "SHA-1" as noted [http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#MessageDigest here].) |
As Clojure is interoperable with Java the solution to this task would be a small modification to [[MD5#Clojure|MD5]], as with Java. (Replacing "MD5" with "SHA-1" as noted [http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#MessageDigest here].) |
||
=={{header|Common Lisp}}== |
|||
{{libheader|ironclad}} |
|||
This example uses the [http://method-combination.net/lisp/ironclad/ Ironclad] cryptography library (available via Quicklisp as well). |
|||
<syntaxhighlight 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)))) |
|||
</syntaxhighlight> |
|||
=={{header|Crystal}}== |
|||
<syntaxhighlight lang="ruby">require "openssl" |
|||
puts OpenSSL::Digest.new("sha1").update("Rosetta Code")</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|D}}== |
|||
'''First:''' Use native 'std.digest.sha' library |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="d">void main() { |
|||
import std.stdio, std.digest.sha; |
|||
writefln("%-(%02x%)", "Ars longa, vita brevis".sha1Of); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>e640d285242886eb96ab80cbf858389b3df52f43</pre> |
|||
'''Second:''' Re-implement SHA-1 in D |
|||
<syntaxhighlight 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)); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|Delphi}}== |
|||
{{libheader| System.SysUtils}} |
|||
{{libheader| DCPsha1}} Part of '''DCPcrypt Cryptographic Component Library v2.1'''[https://bitbucket.org/wpostma/dcpcrypt2010] by David Barton. |
|||
<syntaxhighlight lang="delphi"> |
|||
program Sha_1; |
|||
{$APPTYPE CONSOLE} |
|||
uses |
|||
System.SysUtils, |
|||
DCPsha1; |
|||
function SHA1(const Str: string): string; |
|||
var |
|||
HashDigest: array of byte; |
|||
d: Byte; |
|||
begin |
|||
Result := ''; |
|||
with TDCP_sha1.Create(nil) do |
|||
begin |
|||
Init; |
|||
UpdateStr(Str); |
|||
SetLength(HashDigest, GetHashSize div 8); |
|||
final(HashDigest[0]); |
|||
for d in HashDigest do |
|||
Result := Result + d.ToHexString(2); |
|||
Free; |
|||
end; |
|||
end; |
|||
begin |
|||
Writeln(SHA1('Rosetta Code')); |
|||
readln; |
|||
end.</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5 |
|||
</pre> |
|||
=={{header|DWScript}}== |
|||
<syntaxhighlight lang="delphi">PrintLn( HashSHA1.HashData('Rosetta code') );</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
b18c883f4da750164b5af362ea9b9f27f90904b4 |
|||
</pre> |
|||
=={{header|Elixir}}== |
|||
Uses Erlang module 'crypto' |
|||
{{trans|Erlang}} |
|||
<syntaxhighlight lang="elixir"> |
|||
iex(1)> :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>> |
|||
</syntaxhighlight> |
|||
=={{header|Emacs Lisp}}== |
|||
<syntaxhighlight lang="lisp"> |
|||
(sha1 "Rosetta Code") ;=> "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5" |
|||
(secure-hash 'sha1 "Rosetta Code") ;=> "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5" |
|||
</syntaxhighlight> |
|||
=={{header|Erlang}}== |
|||
{{out}} |
|||
<pre> |
|||
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>> |
|||
</pre> |
|||
=={{header|F_Sharp|F#}}== |
|||
<syntaxhighlight lang="fsharp"> |
|||
let n = System.Security.Cryptography.SHA1.Create() |
|||
Array.iter (printf "%x ") (n.ComputeHash "Rosetta Code"B) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48 c9 8f 7e 5a 6e 73 6d 79 a b7 40 df c3 f5 1a 61 ab e2 b5 |
|||
</pre> |
|||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
Line 58: | Line 1,453: | ||
The implementation is at [https://github.com/slavapestov/factor/blob/master/basis/checksums/sha/sha.factor basis/checksums/sha/sha.factor]. |
The implementation is at [https://github.com/slavapestov/factor/blob/master/basis/checksums/sha/sha.factor 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 |
|||
=={{header|Fortran}}== |
|||
===Intel Fortran on Windows=== |
|||
Using Windows API. See [https://msdn.microsoft.com/en-us/library/aa379886.aspx CryptAcquireContext], [https://msdn.microsoft.com/en-us/library/aa379908.aspx CryptCreateHash], [https://msdn.microsoft.com/en-us/library/aa380202.aspx CryptHashData] and [https://msdn.microsoft.com/en-us/library/aa379947.aspx CryptGetHashParam] on MSDN. |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
=={{header|FreeBASIC}}== |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Rosetta Code => 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5</pre> |
|||
=={{header|Frink}}== |
|||
Frink has convenience methods to use any message hashing algorithm provided by your Java Virtual Machine. The result can be returned as a hexadecimal string, an integer, or an array of bytes. |
|||
<syntaxhighlight lang="frink">println[messageDigest["Rosetta Code", "SHA-1"]]</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Genie}}== |
|||
SHA-1, being overtaken, is not recommended but is supported in GLib checksum, ''ChecksumType.SHA1''. |
|||
<syntaxhighlight lang="genie">print Checksum.compute_for_string(ChecksumType.SHA1, "Rosetta code", -1)</syntaxhighlight> |
|||
(The -1 is NUL byte terminated string indicator for length) |
|||
See [[SHA-256#Genie]]. |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 70: | Line 1,697: | ||
h.Write([]byte("Rosetta Code")) |
h.Write([]byte("Rosetta Code")) |
||
fmt.Printf("%x\n", h.Sum(nil)) |
fmt.Printf("%x\n", h.Sum(nil)) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
||
</pre> |
</pre> |
||
=={{header|Halon}}== |
|||
<syntaxhighlight lang="halon">$var = "Rosetta Code"; |
|||
echo sha1($var);</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Hare}}== |
|||
<syntaxhighlight lang="hare">use crypto::sha1; |
|||
use encoding::hex; |
|||
use fmt; |
|||
use hash; |
|||
use os; |
|||
use strings; |
|||
export fn main() void = { |
|||
const sha = sha1::sha1(); |
|||
hash::write(&sha, strings::toutf8("Rosetta Code")); |
|||
let sum: [sha1::SIZE]u8 = [0...]; |
|||
hash::sum(&sha, sum); |
|||
hex::encode(os::stdout, sum)!; |
|||
fmt::println()!; |
|||
};</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Haskell}}== |
|||
<syntaxhighlight 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" |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
Rosetta Code SHA1-codiert: 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Haxe}}== |
|||
<syntaxhighlight lang="haxe">import haxe.crypto.Sha1; |
|||
class Main { |
|||
static function main() { |
|||
var sha1 = Sha1.encode("Rosetta Code"); |
|||
Sys.println(sha1); |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|J}}== |
|||
From J8 the <tt>ide/qt</tt> addon includes bindings to the Qt library function for a number of hash algorithms incluing SHA-1. Thus: |
|||
<syntaxhighlight lang="j"> require '~addons/ide/qt/qt.ijs' |
|||
getsha1=: 'sha1'&gethash_jqtide_ |
|||
getsha1 'Rosetta Code' |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</syntaxhighlight> |
|||
From J8.06, the sha family of hashes have builtin support. |
|||
<syntaxhighlight lang="j"> sha1=:128!:6 |
|||
sha1'Rosetta Code' |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</syntaxhighlight> |
|||
A implementation of SHA-1 in J follows: |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
Example use: |
|||
<syntaxhighlight lang="j"> text2bits=: (8#2) ,@:#: a. i. ] |
|||
bits2hex=: '0123456789abcdef' {~ _4 #.\ , |
|||
bits2hex sha1 text2bits 'Rosetta Code' |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</syntaxhighlight> |
|||
Remember that SHA-1 is an obsolete standard (and if you *really* want high speed you'd probably be using [[wp:Application-specific_integrated_circuit|ASICs]] rather than a general purpose computing platform). |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
The solution to this task would be a small modification to [[MD5#Java|MD5]] (replacing "MD5" with "SHA-1" as noted [http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#MessageDigest here]). |
The solution to this task would be a small modification to [[MD5#Java|MD5]] (replacing "MD5" with "SHA-1" as noted [http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#MessageDigest here]). |
||
===Implementation=== |
|||
=={{header|Mathematica}}== |
|||
A direct implementation of the SHA-1 algorithm. |
|||
<lang Mathematica>IntegerString[Hash["Rosetta Code", "SHA1"], 16] |
|||
<syntaxhighlight lang="java"> |
|||
import java.nio.charset.StandardCharsets; |
|||
import java.util.Arrays; |
|||
public final class SHA1Task { |
|||
-> 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</lang> |
|||
public static void main(String[] args) { |
|||
System.out.println(SHA1.messageDigest("Rosetta Code")); |
|||
} |
|||
} |
|||
final class SHA1 { |
|||
public static String messageDigest(String message) { |
|||
int[] state = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }; |
|||
byte[] bytes = addPadding(message); |
|||
for ( int i = 0; i < bytes.length / BLOCK_LENGTH; i++ ) { |
|||
int[] values = new int[80]; |
|||
for ( int j = 0; j < BLOCK_LENGTH; j++ ) { |
|||
values[j / 4] |= ( bytes[i * BLOCK_LENGTH + j] & 0xff ) << ( ( 3 - j % 4 ) * 8 ); |
|||
} |
|||
for ( int j = 16; j < 80; j++ ) { |
|||
values[j] = Integer.rotateLeft(values[j - 3] ^ values[j - 8] ^ values[j - 14] ^ values[j - 16], 1); |
|||
} |
|||
int a = state[0], b = state[1], c = state[2], d = state[3], e = state[4]; |
|||
int f = 0, k = 0; |
|||
for ( int j = 0; j < 80; j++ ) { |
|||
switch ( j / 20 ) { |
|||
case 0 -> { f = ( b & c ) | ( ~b & d ); k = 0x5a827999; } |
|||
case 1 -> { f = b ^ c ^ d; k = 0x6ed9eba1; } |
|||
case 2 -> { f = ( b & c ) | ( b & d ) | ( c & d ); k = 0x8f1bbcdc; } |
|||
case 3 -> { f = b ^ c ^ d; k = 0xca62c1d6; } |
|||
} |
|||
int temp = Integer.rotateLeft(a, 5) + f + e + k + values[j]; |
|||
e = d; d = c; c = Integer.rotateLeft(b, 30); b = a; a = temp; |
|||
} |
|||
state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; |
|||
} |
|||
StringBuilder result = new StringBuilder(); |
|||
for ( int i = 0; i < 20; i++ ) { |
|||
result.append(String.format("%02x", ( state[i / 4] >>> 24 - ( i % 4 ) * 8 ) & 0xFF )); |
|||
} |
|||
return result.toString(); |
|||
} |
|||
private static byte[] addPadding(String message) { |
|||
byte[] bytes = message.getBytes(StandardCharsets.UTF_8); |
|||
bytes = Arrays.copyOf(bytes, bytes.length + 1); |
|||
bytes[bytes.length - 1] = (byte) 0x80; |
|||
int padding = BLOCK_LENGTH - ( bytes.length % BLOCK_LENGTH ); |
|||
if ( padding < 8 ) { |
|||
padding += BLOCK_LENGTH; |
|||
} |
|||
bytes = Arrays.copyOf(bytes, bytes.length + padding); |
|||
final long bitLength = message.length() * 8; |
|||
for ( int i = 0; i < 8; i++ ) { |
|||
bytes[bytes.length - 1 - i] = (byte) ( bitLength >>> ( 8 * i ) ); |
|||
} |
|||
return bytes; |
|||
} |
|||
private static final int BLOCK_LENGTH = 64; |
|||
} |
|||
</syntaxhighlight> |
|||
{{ out }} |
|||
<pre> |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Jsish}}== |
|||
<syntaxhighlight lang="javascript">/* SHA-1 hash in Jsish */ |
|||
var str = 'Rosetta code'; |
|||
puts(Util.hash(str, {type:'sha1'})); |
|||
/* |
|||
=!EXPECTSTART!= |
|||
b18c883f4da750164b5af362ea9b9f27f90904b4 |
|||
=!EXPECTEND!= |
|||
*/</syntaxhighlight> |
|||
{{out}} |
|||
<pre>prompt$ jsish sha-1.jsi |
|||
b18c883f4da750164b5af362ea9b9f27f90904b4 |
|||
prompt$ jsish -u sha-1.jsi |
|||
[PASS] sha-1.jsi</pre> |
|||
=={{header|Julia}}== |
|||
{{works with|Julia|0.6}} |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
{{out}} |
|||
<pre># abc |
|||
-> digest: a9993e364706816aba3e25717850c26c9cd0d89d |
|||
-> expect: a9993e364706816aba3e25717850c26c9cd0d89d |
|||
# abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomn... |
|||
-> digest: 84983e441c3bd26ebaae4aa1f95129e5e54670f1 |
|||
-> expect: 84983e441c3bd26ebaae4aa1f95129e5e54670f1 |
|||
# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... |
|||
-> digest: 34aa973cd4c4daa4f61eeb2bdbad27316534016f |
|||
-> expect: 34aa973cd4c4daa4f61eeb2bdbad27316534016f</pre> |
|||
=={{header|Kotlin}}== |
|||
<syntaxhighlight 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() |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Lasso}}== |
|||
<syntaxhighlight lang="lasso">cipher_digest('Rosetta Code', -digest='SHA1',-hex=true)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 </pre> |
|||
=={{header|Liberty BASIC}}== |
|||
<syntaxhighlight 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 |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5</pre> |
|||
=={{header|Lingo}}== |
|||
{{libheader|Crypto Xtra}} |
|||
<syntaxhighlight lang="lingo">crypto = xtra("Crypto").new() |
|||
put crypto.cx_sha1_string("Rosetta Code")</syntaxhighlight> |
|||
{{out}} |
|||
<pre>-- "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"</pre> |
|||
=={{header|LiveCode}}== |
|||
<syntaxhighlight lang="livecode">command shaRosettaCode |
|||
local shex, sha1 |
|||
put sha1Digest("Rosetta Code") into sha1 |
|||
get binaryDecode("H*",sha1,shex) |
|||
put shex |
|||
end shaRosettaCode</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|Lua}}== |
|||
{{works with|Lua 5.1.4}} |
|||
{{libheader|sha1}} ([https://github.com/kikito/sha1.lua luarocks install sha1]) |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
SHA-1("Rosetta code") = b18c883f4da750164b5af362ea9b9f27f90904b4 |
|||
SHA-1("Rosetta Code") = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Maple}}== |
|||
<syntaxhighlight lang="maple">with(StringTools): |
|||
Hash("Ars longa, vita brevis",method="SHA1"); |
|||
# "e640d285242886eb96ab80cbf858389b3df52f43"</syntaxhighlight> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
|||
<syntaxhighlight lang="text">Hash["Rosetta code","SHA1","HexString"]</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|min}}== |
|||
{{works with|min|0.19.6}} |
|||
<syntaxhighlight lang="min">"Rosetta Code" sha1 puts!</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Neko}}== |
|||
SHA-1 was added in Neko 2.2. |
|||
<syntaxhighlight lang="actionscript">/** |
|||
SHA-1 in Neko |
|||
Tectonics: |
|||
nekoc SHA-1.neko |
|||
neko SHA-1 |
|||
*/ |
|||
var SHA1 = $loader.loadprim("std@make_sha1", 3); |
|||
var base_encode = $loader.loadprim("std@base_encode", 2); |
|||
var msg = "Rosetta Code"; |
|||
var result = SHA1(msg, 0, $ssize(msg)); |
|||
/* Output in lowercase hex */ |
|||
$print(base_encode(result, "0123456789abcdef"));</syntaxhighlight> |
|||
{{out}} |
|||
<pre>prompt$ nekoc SHA-1.neko |
|||
prompt$ neko SHA-1.n |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5prompt$</pre> |
|||
=={{header|NetRexx}}== |
|||
This solution is basically the same as that for [[MD5#NetRExx|MD5]], substituting "SHA-1" for "MD5" as the algorithm to use in the <tt>MessageDigest</tt> instance. |
|||
<syntaxhighlight 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 |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
<Message>Rosetta Code</Message> |
|||
<SHA-1>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</SHA-1> |
|||
<Verify>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</Verify> |
|||
SHA-1 Confirmed |
|||
</pre> |
|||
=={{header|NewLISP}}== |
|||
<syntaxhighlight 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")</syntaxhighlight> |
|||
=={{header|Nim}}== |
|||
Nim standard library provides the module “std/sha1” to compute SHA1 digests. |
|||
<syntaxhighlight lang="nim">import std/sha1 |
|||
echo secureHash("Rosetta Code")</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5</pre> |
|||
=={{header|Oberon-2}}== |
|||
{{works with|oo2c}} {{libheader|crypto}} |
|||
<syntaxhighlight 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. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
SHA1: |
|||
48C98F7E 5A6E736D 790AB740 DFC3F51A 61ABE2B5 |
|||
</pre> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Line 88: | Line 2,245: | ||
Using the library <code>ocaml-sha</code> in the interactive loop: |
Using the library <code>ocaml-sha</code> in the interactive loop: |
||
< |
<syntaxhighlight lang="ocaml">$ ocaml -I +sha sha1.cma |
||
Objective Caml version 3.12.1 |
Objective Caml version 3.12.1 |
||
# Sha1.to_hex (Sha1.string "Rosetta Code") ;; |
# Sha1.to_hex (Sha1.string "Rosetta Code") ;; |
||
- : string = "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"</ |
- : string = "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"</syntaxhighlight> |
||
=={{header|Octave}}== |
|||
Normally SHA-1 is available in the [http://octave.sourceforge.net/general/function/SHA1.html general package]. |
|||
<syntaxhighlight lang="octave">sprintf("%02x", SHA1(+"Rosetta Code"(:)))</syntaxhighlight> |
|||
{{out}} |
|||
<pre>ans = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|PARI/GP}}== |
|||
It works on Linux systems. |
|||
<syntaxhighlight lang="parigp">sha1(s)=extern("echo \"Str(`echo -n '"Str(s)"'|sha1sum|cut -d' ' -f1`)\"")</syntaxhighlight> |
|||
The code above creates a new function sha1(s) which returns SHA-1 hash of item s. |
|||
{{out}} |
|||
<pre> |
|||
sha1("Rosetta Code") = "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5" |
|||
sha1(1+2) = "77de68daecd823babbb58edb1c8e14d7106e83bb" ; sha(3) |
|||
</pre> |
|||
=={{header|Pascal}}== |
|||
{{works with|Free_Pascal}} {{libheader|sha1}} |
|||
<syntaxhighlight lang="pascal">program RosettaSha1; |
|||
uses |
|||
sha1; |
|||
var |
|||
d: TSHA1Digest; |
|||
begin |
|||
d:=SHA1String('Rosetta Code'); |
|||
WriteLn(SHA1Print(d)); |
|||
end.</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|Perl}}== |
|||
{{libheader|Digest::SHA}} |
|||
<syntaxhighlight lang="perl">use Digest::SHA qw(sha1_hex); |
|||
print sha1_hex('Rosetta Code'), "\n";</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
The same in OO manner |
|||
<syntaxhighlight lang="perl">use Digest::SHA; |
|||
my $sha1 = Digest::SHA->new(1); |
|||
$sha1->add('Rosetta Code'); |
|||
print $sha1->hexdigest, "\n";</syntaxhighlight> |
|||
=={{header|Phix}}== |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
-- demo\rosetta\sha1.exw |
|||
-- ===================== |
|||
-- |
|||
-- NB no longer considered secure. Non-optimised. |
|||
--</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">uint32</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">and_bitsu</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#FFFFFFFF</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">sq_uint32</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">uint32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">dword</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000080;font-style:italic;">-- get dword as big-endian</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">#1000000</span><span style="color: #0000FF;">+</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">#10000</span><span style="color: #0000FF;">+</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">#100</span><span style="color: #0000FF;">+</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">xor_all</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">result</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">uint32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">result</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">word</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">bits</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000080;font-style:italic;">-- left rotate the bits of a 32-bit number by the specified number of bits</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">uint32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">word</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bits</span><span style="color: #0000FF;">))+</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">word</span><span style="color: #0000FF;">/</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32</span><span style="color: #0000FF;">-</span><span style="color: #000000;">bits</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">sha1</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">temp</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">80</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">h0</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0x67452301</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">h1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0xefcdab89</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">h2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0x98badcfe</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">h3</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0x10325476</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">h4</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0xc3d2e1f0</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">bits</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">8</span> |
|||
<span style="color: #000000;">msg</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">#80</span> |
|||
<span style="color: #008080;">while</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">),</span><span style="color: #000000;">64</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">56</span> <span style="color: #008080;">do</span> <span style="color: #000000;">msg</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'\0'</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
<span style="color: #000000;">msg</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">int_to_bytes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bits</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">chunk</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #000000;">64</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">16</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">w</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dword</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chunk</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">17</span> <span style="color: #008080;">to</span> <span style="color: #000000;">80</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">w</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xor_all</span><span style="color: #0000FF;">({</span><span style="color: #000000;">w</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">],</span><span style="color: #000000;">w</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">8</span><span style="color: #0000FF;">],</span><span style="color: #000000;">w</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">14</span><span style="color: #0000FF;">],</span><span style="color: #000000;">w</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">16</span><span style="color: #0000FF;">]}),</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">h0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h4</span><span style="color: #0000FF;">}</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">80</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">20</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">temp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">),</span><span style="color: #000000;">d</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#5A827999</span> |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">40</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">temp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">),</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#6ED9EBA1</span> |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">60</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">temp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)),</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#8F1BBCDC</span> |
|||
<span style="color: #008080;">else</span> <span style="color: #000080;font-style:italic;">-- i<=80</span> |
|||
<span style="color: #000000;">temp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">),</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#CA62C1D6</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">uint32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">temp</span><span style="color: #0000FF;">+</span><span style="color: #000000;">e</span><span style="color: #0000FF;">+</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">w</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]),</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">30</span><span style="color: #0000FF;">),</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">h0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h4</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sq_uint32</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">({</span><span style="color: #000000;">h0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h4</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">}))</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">h0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h4</span><span style="color: #0000FF;">}</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%08X"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #0000FF;">?</span><span style="color: #000000;">sha1</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Rosetta Code"</span><span style="color: #0000FF;">)</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{out}} |
|||
<pre> |
|||
"48c98f7e 5a6e736d 790ab740 dfc3f51a 61abe2b5" |
|||
</pre> |
|||
=={{header|PHP}}== |
|||
<syntaxhighlight lang="php"><?php |
|||
$string = 'Rosetta Code'; |
|||
echo sha1( $string ), "\n"; |
|||
?></syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|PicoLisp}}== |
|||
Library and implementation. |
|||
<syntaxhighlight 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)</syntaxhighlight> |
|||
=={{header|Pike}}== |
|||
<syntaxhighlight lang="pike"> |
|||
string input = "Rosetta Code"; |
|||
string out = Crypto.SHA1.hash(input); |
|||
write( String.string2hex(out) +"\n"); |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|PowerShell}}== |
|||
<syntaxhighlight 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) |
|||
} |
|||
</syntaxhighlight> |
|||
taken from [http://stackoverflow.com/questions/8051713/convert-a-string-to-a-byte-array-in-powershell-version-2 Stackoverflow] with a little modification |
|||
=={{header|Prolog}}== |
|||
{{works with|SWI-Prolog}} |
|||
SWI-Prolog has SHA1 hashing as the default in its <code>sha_hash</code> function. |
|||
<syntaxhighlight lang="Prolog">:- use_module(library(sha)). |
|||
sha_hex(Str,Hex):- |
|||
sha_hash(Str, Hash, []), |
|||
hash_atom(Hash, Hex).</syntaxhighlight> |
|||
<syntaxhighlight lang="Prolog">?- sha_hex("Rosetta Code",Hex). |
|||
Hex = '48c98f7e5a6e736d790ab740dfc3f51a61abe2b5'.</syntaxhighlight> |
|||
=={{header|PureBasic}}== |
|||
PB Version 5.40 |
|||
<syntaxhighlight lang="purebasic">a$="Rosetta Code" |
|||
UseSHA1Fingerprint() : b$=StringFingerprint(a$, #PB_Cipher_SHA1) |
|||
OpenConsole() |
|||
Print("[SHA1] Text: "+a$+" ==> "+b$) |
|||
Input()</syntaxhighlight> |
|||
{{out}} |
|||
<pre>[SHA1] Text: Rosetta Code ==> 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|Python}}== |
|||
<syntaxhighlight lang="python">import hashlib |
|||
h = hashlib.sha1() |
|||
h.update(bytes("Ars longa, vita brevis", encoding="ASCII")) |
|||
h.hexdigest() |
|||
# "e640d285242886eb96ab80cbf858389b3df52f43"</syntaxhighlight> |
|||
=={{header|R}}== |
|||
<syntaxhighlight lang="rsplus"> |
|||
library(digest) |
|||
input <- "Rosetta Code" |
|||
cat(digest(input, algo = "sha1", serialize = FALSE), "\n") |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Racket}}== |
|||
With the built-in <tt>file/sha1</tt> library: |
|||
<syntaxhighlight lang="racket"> |
|||
#lang racket |
|||
(require file/sha1) |
|||
(sha1 (open-input-string "Rosetta Code")) |
|||
</syntaxhighlight> |
|||
With the faster <tt>openssl/sha1</tt> library (requires OpenSSL to be installed): |
|||
<syntaxhighlight lang="racket"> |
|||
#lang racket |
|||
(require openssl/sha1) |
|||
(sha1 (open-input-string "Rosetta Code")) |
|||
</syntaxhighlight> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
===Pure Raku=== |
|||
A pure Raku implementation that closely follows the description of SHA-1 in FIPS 180-1. Slow. |
|||
<syntaxhighlight lang="raku" line>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';</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>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</pre> |
|||
===Library based implementation=== |
|||
Quite speedy. |
|||
<syntaxhighlight lang="raku" line>use Digest::SHA1::Native; |
|||
# use sha1-hex() if you want a hex string |
|||
say sha1($_), " $_" for |
|||
'abc', |
|||
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', |
|||
'Rosetta Code', |
|||
'Ars longa, vita brevis' |
|||
;</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>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</pre> |
|||
=={{header|Ring}}== |
|||
<syntaxhighlight lang="ring"> |
|||
# Project : SHA-1 |
|||
load "stdlib.ring" |
|||
str = "Rosetta Code" |
|||
see "String: " + str + nl |
|||
see "SHA-1: " |
|||
see sha1(str) + nl |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
String: Rosetta Code |
|||
SHA-1: 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Line 98: | Line 2,697: | ||
'''First:''' Use 'digest' from Ruby's standard library. |
'''First:''' Use 'digest' from Ruby's standard library. |
||
< |
<syntaxhighlight lang="ruby">require 'digest' |
||
puts Digest::SHA1.hexdigest('Rosetta Code')</ |
puts Digest::SHA1.hexdigest('Rosetta Code')</syntaxhighlight> |
||
'''Second:''' Use 'openssl' from Ruby's standard library. {{libheader|OpenSSL}} |
'''Second:''' Use 'openssl' from Ruby's standard library. {{libheader|OpenSSL}} |
||
< |
<syntaxhighlight lang="ruby">require 'openssl' |
||
puts OpenSSL::Digest::SHA1.hexdigest('Rosetta Code')</ |
puts OpenSSL::Digest::SHA1.hexdigest('Rosetta Code')</syntaxhighlight> |
||
'''Third:''' Reimplement SHA-1 in Ruby. |
'''Third:''' Reimplement SHA-1 in Ruby. |
||
< |
<syntaxhighlight lang="ruby">require 'stringio' |
||
# Calculates SHA-1 message digest of _string_. Returns |
# Calculates SHA-1 message digest of _string_. Returns binary digest. |
||
# For hexadecimal digest, use +*sha1(string).unpack('H*')+. |
|||
# binary string. |
|||
#-- |
#-- |
||
# This is a simple, pure-Ruby implementation of SHA-1, following |
# This is a simple, pure-Ruby implementation of SHA-1, following |
||
Line 116: | Line 2,715: | ||
def sha1(string) |
def sha1(string) |
||
# functions and constants |
# functions and constants |
||
mask = |
mask = 0xffffffff |
||
s = proc{|n, x| ((x << n) & mask) | (x >> (32 - n))} |
s = proc{|n, x| ((x << n) & mask) | (x >> (32 - n))} |
||
f = [ |
f = [ |
||
Line 125: | Line 2,724: | ||
].freeze |
].freeze |
||
k = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6].freeze |
k = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6].freeze |
||
# initial hash |
# initial hash |
||
h = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0] |
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) |
io = StringIO.new(string) |
||
block = "" |
block = "" |
||
term = false # appended "\x80" in second-last block? |
|||
while io.read(64, block) |
|||
w = block.unpack("N16") |
|||
until last |
|||
# Read next block of 16 words (64 bytes, 512 bits). |
|||
io.read(64, block) |
|||
# Unpack block into 32-bit words "N". |
|||
case len = block.length |
|||
when 64 |
|||
# Unpack 16 words. |
|||
w = block.unpack("N16") |
|||
when 56..63 |
|||
# Second-last block: append padding, unpack 16 words. |
|||
block.concat("\x80"); term = true |
|||
block.concat("\0" * (63 - len)) |
|||
w = block.unpack("N16") |
|||
when 0..55 |
|||
# Last block: append padding, unpack 14 words. |
|||
block.concat(term ? "\0" : "\x80") |
|||
block.concat("\0" * (55 - len)) |
|||
w = block.unpack("N14") |
|||
# Append bit length, 2 words. |
|||
bit_len = string.length << 3 |
|||
w.push(bit_len >> 32, bit_len & mask) |
|||
last = true |
|||
else |
|||
fail "impossible" |
|||
end |
|||
# Process block. |
# Process block. |
||
(16..79).each {|t| |
(16..79).each {|t| w[t] = s[1, w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16]]} |
||
w[t] = s[1, w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]]} |
|||
a, b, c, d, e = h |
|||
a, b, c, d, e = h[0..4] |
|||
t = 0 |
t = 0 |
||
4.times do |i| |
|||
20.times |
20.times do |
||
temp = (s[5, a] + f[i][b, c, d] + e + w[t] + k[i]) & mask |
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 |
t += 1 |
||
end |
|||
end |
|||
h[0] = (h[0] + a) & mask |
|||
h[1] = (h[1] + b) & mask |
|||
h[ |
[a,b,c,d,e].each_with_index {|x,i| h[i] = (h[i] + x) & mask} |
||
h[3] = (h[3] + d) & mask |
|||
h[4] = (h[4] + e) & mask |
|||
end |
end |
||
h.pack("N5") |
h.pack("N5") |
||
end |
end |
||
# Hexadecimal-encode a binary _string_. |
|||
def hexencode(string) |
|||
# We use String#each_byte for compatibility with Ruby 1.8.6. |
|||
result = "" |
|||
string.each_byte {|byte| result << ("%02x" % byte)} |
|||
result |
|||
end |
|||
if __FILE__ == $0 |
if __FILE__ == $0 |
||
# Print some example SHA-1 digests. |
# Print some example SHA-1 digests. |
||
# FIPS 180-1 has correct digests for 'abc' and 'abc...opq'. |
# FIPS 180-1 has correct digests for 'abc' and 'abc...opq'. |
||
[ |
[ 'abc', |
||
'abc', |
|||
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', |
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', |
||
'Rosetta Code', |
'Rosetta Code', |
||
].each {|s| |
].each {|s| printf("%s:\n %s\n", s, *sha1(s).unpack('H*'))} |
||
end</syntaxhighlight> |
|||
printf("%s:\n %s\n", s, hexencode(sha1 s)) |
|||
{{out}} |
|||
<pre> |
|||
abc: |
|||
a9993e364706816aba3e25717850c26c9cd0d89d |
|||
abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq: |
|||
84983e441c3bd26ebaae4aa1f95129e5e54670f1 |
|||
Rosetta Code: |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Rust}}== |
|||
Using sha1 crate: https://docs.rs/sha1/0.6.0/sha1/ |
|||
<syntaxhighlight 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()); |
|||
} |
|||
</syntaxhighlight> |
|||
Output |
|||
<pre> |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|S-lang}}== |
|||
Support for MD5 and SHA-1 are included in the standard "chksum" library: |
|||
<syntaxhighlight lang="s-lang">require("chksum"); |
|||
print(sha1sum("Rosetta Code"));</syntaxhighlight> |
|||
{{out}} |
|||
<pre>"48c98f7e5a6e736d790ab740dfc3f51a61abe2b5" |
|||
</pre> |
|||
=={{header|Scala}}== |
|||
The solution to this task would be a small modification to [[MD5#Scala|MD5]] (replacing "MD5" with "SHA-1" as noted [http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#MessageDigest here]). |
|||
<syntaxhighlight 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)) |
|||
} |
} |
||
end</lang> |
|||
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")) |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|Scheme}}== |
|||
{{works with|Ol}} |
|||
<syntaxhighlight 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))))))))) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<syntaxhighlight 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 |
|||
</syntaxhighlight> |
|||
=={{header|Seed7}}== |
|||
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i"; |
|||
include "msgdigest.s7i"; |
|||
const proc: main is func |
|||
begin |
|||
writeln(hex(sha1("Rosetta Code"))); |
|||
end func;</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Sidef}}== |
|||
<syntaxhighlight lang="ruby">var sha = frequire('Digest::SHA'); |
|||
say sha.sha1_hex('Rosetta Code');</syntaxhighlight> |
|||
{{out}} |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
|||
=={{header|Smalltalk}}== |
|||
{{works with|GNU Smalltalk}} |
|||
<syntaxhighlight lang="smalltalk">PackageLoader fileInPackage: 'Digest'. |
|||
(SHA1 hexDigestOf: 'Rosetta Code') displayNl.</syntaxhighlight> |
|||
{{works with|Smalltalk/X}} |
|||
<syntaxhighlight lang="smalltalk">(SHA1Stream hashValueOf:'Rosetta Code')</syntaxhighlight> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{tcllib|sha1}} |
{{tcllib|sha1}} |
||
< |
<syntaxhighlight lang="tcl">package require sha1 |
||
puts [sha1::sha1 "Rosetta Code"]</ |
puts [sha1::sha1 "Rosetta Code"]</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
<pre>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</pre> |
||
It should be noted that the <code>sha1</code> package is actually a façade that uses an efficient implementation in [[C]] if one is available, or a pure Tcl version otherwise. |
It should be noted that the <code>sha1</code> package is actually a façade that uses an efficient implementation in [[C]] if one is available, or a pure Tcl version otherwise. |
||
Line 213: | Line 3,127: | ||
=={{header|UNIX Shell}}== |
=={{header|UNIX Shell}}== |
||
{{works with|OpenBSD|2.2 [http://www.openbsd.org/cgi-bin/cvsweb/src/bin/md5/Makefile (link)]}} |
{{works with|OpenBSD|2.2 [http://www.openbsd.org/cgi-bin/cvsweb/src/bin/md5/Makefile (link)]}} |
||
< |
<syntaxhighlight lang="bash">$ echo -n 'ASCII string' | sha1 |
||
9e9aeefe5563845ec5c42c5630842048c0fc261b</ |
9e9aeefe5563845ec5c42c5630842048c0fc261b</syntaxhighlight> |
||
{{libheader|OpenSSL}} |
{{libheader|OpenSSL}} |
||
< |
<syntaxhighlight lang="bash">$ echo -n 'ASCII string' | openssl sha1 | sed 's/.*= //' |
||
9e9aeefe5563845ec5c42c5630842048c0fc261b</ |
9e9aeefe5563845ec5c42c5630842048c0fc261b</syntaxhighlight> |
||
=={{header|V (Vlang)}}== |
|||
<syntaxhighlight lang="v (vlang)">import crypto.sha1 |
|||
fn main() { |
|||
println("${sha1.hexhash('Rosetta Code')}")//Rosetta code |
|||
mut h := sha1.new() |
|||
h.write('Rosetta Code'.bytes()) ? |
|||
println('${h.checksum().map(it.hex()).join('')}') |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
{{libheader|Wren-crypto}} |
|||
{{libheader|Wren-fmt}} |
|||
<syntaxhighlight lang="wren">import "./crypto" for Sha1 |
|||
import "./fmt" for Fmt |
|||
var strings = [ |
|||
"", |
|||
"a", |
|||
"abc", |
|||
"message digest", |
|||
"abcdefghijklmnopqrstuvwxyz", |
|||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", |
|||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", |
|||
"The quick brown fox jumps over the lazy dog", |
|||
"The quick brown fox jumps over the lazy cog", |
|||
"Rosetta Code" |
|||
] |
|||
for (s in strings) { |
|||
var hash = Sha1.digest(s) |
|||
Fmt.print("$s <== '$0s'", hash, s) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
da39a3ee5e6b4b0d3255bfef95601890afd80709 <== '' |
|||
86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 <== 'a' |
|||
a9993e364706816aba3e25717850c26c9cd0d89d <== 'abc' |
|||
c12252ceda8be8994d5fa0290a47231c1d16aae3 <== 'message digest' |
|||
32d10c7b8cf96570ca04ce37f2a19d84240d3a89 <== 'abcdefghijklmnopqrstuvwxyz' |
|||
761c457bf73b14d27e9e9265c46f4b4dda11f940 <== 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' |
|||
50abf5706a150990a08b2c5ea40fa0e585554732 <== '12345678901234567890123456789012345678901234567890123456789012345678901234567890' |
|||
2fd4e1c67a2d28fced849ee1bb76e7391b93eb12 <== 'The quick brown fox jumps over the lazy dog' |
|||
de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3 <== 'The quick brown fox jumps over the lazy cog' |
|||
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 <== 'Rosetta Code' |
|||
</pre> |
|||
=={{header|zkl}}== |
|||
Using zklMsgHash so. Can return the hash as a string of hex digits or bytes, can hash the hash N times. |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
{{omit from|Lilypond}} |
|||
{{omit from|TUSCRIPT}} |
Latest revision as of 15:23, 5 February 2024
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
/* 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"
- Output:
Rosetta Code => 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5 Program End ok.
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;
- Output:
SHA1 ("Rosetta Code") = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
ARM Assembly
with openssl library
/* 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"
with only instructions assembly ARM
/* 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"
- Output:
Rosetta Code => 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5 Program End ok.
Arturo
print digest.sha "The quick brown fox jumped over the lazy dog's back"
- Output:
9f2cbbcba105f1390db79a263af5bf9554f935a4
Astro
import crypto { sha1 }
let hash = sha1.hexdigest('Ars longa, vita brevis')
print hash
AutoHotkey
Source: SHA-1 @github by jNizM
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)
}
- Output:
String: Rosetta Code SHA-1: 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
BBC BASIC
Library
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$
- Output:
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
Native
*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#
- Output:
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
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;
}
C#
Tests the built-in SHA1CryptoServiceProvider:
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));
}
}
}
C++
Compiling with g++ -lPocoCrypto shaexample.cpp -o shaexample
:
#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 ;
}
- Output:
Rosetta Code as a sha1 digest :48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 !
Without external libraries
#include <bit>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
class SHA1 {
public:
std::string message_digest(const std::string& message) {
std::vector<uint32_t> state = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
const std::vector<int8_t> bytes = add_padding(message);
for ( uint64_t i = 0; i < bytes.size() / BLOCK_LENGTH; ++i ) {
std::vector<uint32_t> values(80, 0);
for ( uint32_t j = 0; j < BLOCK_LENGTH; ++j ) {
values[j / 4] |= ( bytes[i * BLOCK_LENGTH + j] & 0xff ) << ( ( 3 - j % 4 ) * 8 );
}
for ( uint32_t j = 16; j < 80; ++j ) {
uint32_t value = values[j - 3] ^ values[j - 8] ^ values[j - 14] ^ values[j - 16];
values[j] = std::rotl(value, 1);
}
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
uint32_t f = 0, k = 0;
for ( uint32_t j = 0; j < 80; ++j ) {
switch ( j / 20 ) {
case 0 : { f = ( b & c ) | ( ~b & d ); k = 0x5a827999; break; }
case 1 : { f = b ^ c ^ d; k = 0x6ed9eba1; break; }
case 2 : { f = ( b & c ) | ( b & d ) | ( c & d ); k = 0x8f1bbcdc; break; }
case 3 : { f = b ^ c ^ d; k = 0xca62c1d6; break; }
}
uint32_t temp = std::rotl(a, 5) + f + e + k + values[j];
e = d; d = c; c = std::rotl(b, 30); b = a; a = temp;
}
state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e;
}
std::stringstream stream;
for ( uint32_t i = 0; i < 20; ++i ) {
int8_t byte_value = static_cast<int8_t>(state[i / 4] >> ( 24 - ( i % 4 ) * 8));
stream << std::setfill('0') << std::setw(2) << std::hex << ( byte_value & 0xff );
}
return stream.str();
}
private:
std::vector<int8_t> add_padding(const std::string& message) {
std::vector<int8_t> bytes(message.begin(), message.end());
bytes.emplace_back(static_cast<uint8_t>(0x80));
uint32_t padding = BLOCK_LENGTH - ( bytes.size() % BLOCK_LENGTH );
if ( padding < 8 ) {
padding += BLOCK_LENGTH;
}
bytes.resize(bytes.size() + padding - 8, static_cast<int8_t>(0x0));
const uint64_t bit_length = 8 * message.length();
for ( int32_t i = 7; i >= 0; --i ) {
bytes.emplace_back(static_cast<int8_t>(bit_length >> ( 8 * i )));
}
return bytes;
}
const uint32_t BLOCK_LENGTH = 64;
};
int main() {
SHA1 sha1;
std::cout << sha1.message_digest("Rosetta Code") << std::endl;
}
- Output:
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).
;;; 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))))
Crystal
require "openssl"
puts OpenSSL::Digest.new("sha1").update("Rosetta Code")
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
D
First: Use native 'std.digest.sha' library
void main() {
import std.stdio, std.digest.sha;
writefln("%-(%02x%)", "Ars longa, vita brevis".sha1Of);
}
- Output:
e640d285242886eb96ab80cbf858389b3df52f43
Second: Re-implement SHA-1 in 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));
}
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Delphi
Part of DCPcrypt Cryptographic Component Library v2.1[1] by David Barton.
program Sha_1;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
DCPsha1;
function SHA1(const Str: string): string;
var
HashDigest: array of byte;
d: Byte;
begin
Result := '';
with TDCP_sha1.Create(nil) do
begin
Init;
UpdateStr(Str);
SetLength(HashDigest, GetHashSize div 8);
final(HashDigest[0]);
for d in HashDigest do
Result := Result + d.ToHexString(2);
Free;
end;
end;
begin
Writeln(SHA1('Rosetta Code'));
readln;
end.
- Output:
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
DWScript
PrintLn( HashSHA1.HashData('Rosetta code') );
- Output:
b18c883f4da750164b5af362ea9b9f27f90904b4
Elixir
Uses Erlang module 'crypto'
iex(1)> :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>>
Emacs Lisp
(sha1 "Rosetta Code") ;=> "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"
(secure-hash 'sha1 "Rosetta Code") ;=> "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"
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#
let n = System.Security.Cryptography.SHA1.Create()
Array.iter (printf "%x ") (n.ComputeHash "Rosetta Code"B)
- 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.
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
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
- Output:
Rosetta Code => 48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
Frink
Frink has convenience methods to use any message hashing algorithm provided by your Java Virtual Machine. The result can be returned as a hexadecimal string, an integer, or an array of bytes.
println[messageDigest["Rosetta Code", "SHA-1"]]
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Genie
SHA-1, being overtaken, is not recommended but is supported in GLib checksum, ChecksumType.SHA1.
print Checksum.compute_for_string(ChecksumType.SHA1, "Rosetta code", -1)
(The -1 is NUL byte terminated string indicator for length)
See SHA-256#Genie.
Go
package main
import (
"crypto/sha1"
"fmt"
)
func main() {
h := sha1.New()
h.Write([]byte("Rosetta Code"))
fmt.Printf("%x\n", h.Sum(nil))
}
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Halon
$var = "Rosetta Code";
echo sha1($var);
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Hare
use crypto::sha1;
use encoding::hex;
use fmt;
use hash;
use os;
use strings;
export fn main() void = {
const sha = sha1::sha1();
hash::write(&sha, strings::toutf8("Rosetta Code"));
let sum: [sha1::SIZE]u8 = [0...];
hash::sum(&sha, sum);
hex::encode(os::stdout, sum)!;
fmt::println()!;
};
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
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"
- Output:
Rosetta Code SHA1-codiert: 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Haxe
import haxe.crypto.Sha1;
class Main {
static function main() {
var sha1 = Sha1.encode("Rosetta Code");
Sys.println(sha1);
}
}
- 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:
require '~addons/ide/qt/qt.ijs'
getsha1=: 'sha1'&gethash_jqtide_
getsha1 'Rosetta Code'
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
From J8.06, the sha family of hashes have builtin support.
sha1=:128!:6
sha1'Rosetta Code'
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
A implementation of SHA-1 in J follows:
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
Example use:
text2bits=: (8#2) ,@:#: a. i. ]
bits2hex=: '0123456789abcdef' {~ _4 #.\ ,
bits2hex sha1 text2bits 'Rosetta Code'
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
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).
Implementation
A direct implementation of the SHA-1 algorithm.
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public final class SHA1Task {
public static void main(String[] args) {
System.out.println(SHA1.messageDigest("Rosetta Code"));
}
}
final class SHA1 {
public static String messageDigest(String message) {
int[] state = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
byte[] bytes = addPadding(message);
for ( int i = 0; i < bytes.length / BLOCK_LENGTH; i++ ) {
int[] values = new int[80];
for ( int j = 0; j < BLOCK_LENGTH; j++ ) {
values[j / 4] |= ( bytes[i * BLOCK_LENGTH + j] & 0xff ) << ( ( 3 - j % 4 ) * 8 );
}
for ( int j = 16; j < 80; j++ ) {
values[j] = Integer.rotateLeft(values[j - 3] ^ values[j - 8] ^ values[j - 14] ^ values[j - 16], 1);
}
int a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
int f = 0, k = 0;
for ( int j = 0; j < 80; j++ ) {
switch ( j / 20 ) {
case 0 -> { f = ( b & c ) | ( ~b & d ); k = 0x5a827999; }
case 1 -> { f = b ^ c ^ d; k = 0x6ed9eba1; }
case 2 -> { f = ( b & c ) | ( b & d ) | ( c & d ); k = 0x8f1bbcdc; }
case 3 -> { f = b ^ c ^ d; k = 0xca62c1d6; }
}
int temp = Integer.rotateLeft(a, 5) + f + e + k + values[j];
e = d; d = c; c = Integer.rotateLeft(b, 30); b = a; a = temp;
}
state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e;
}
StringBuilder result = new StringBuilder();
for ( int i = 0; i < 20; i++ ) {
result.append(String.format("%02x", ( state[i / 4] >>> 24 - ( i % 4 ) * 8 ) & 0xFF ));
}
return result.toString();
}
private static byte[] addPadding(String message) {
byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
bytes = Arrays.copyOf(bytes, bytes.length + 1);
bytes[bytes.length - 1] = (byte) 0x80;
int padding = BLOCK_LENGTH - ( bytes.length % BLOCK_LENGTH );
if ( padding < 8 ) {
padding += BLOCK_LENGTH;
}
bytes = Arrays.copyOf(bytes, bytes.length + padding);
final long bitLength = message.length() * 8;
for ( int i = 0; i < 8; i++ ) {
bytes[bytes.length - 1 - i] = (byte) ( bitLength >>> ( 8 * i ) );
}
return bytes;
}
private static final int BLOCK_LENGTH = 64;
}
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Jsish
/* SHA-1 hash in Jsish */
var str = 'Rosetta code';
puts(Util.hash(str, {type:'sha1'}));
/*
=!EXPECTSTART!=
b18c883f4da750164b5af362ea9b9f27f90904b4
=!EXPECTEND!=
*/
- Output:
prompt$ jsish sha-1.jsi b18c883f4da750164b5af362ea9b9f27f90904b4 prompt$ jsish -u sha-1.jsi [PASS] sha-1.jsi
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
- Output:
# abc -> digest: a9993e364706816aba3e25717850c26c9cd0d89d -> expect: a9993e364706816aba3e25717850c26c9cd0d89d # abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomn... -> digest: 84983e441c3bd26ebaae4aa1f95129e5e54670f1 -> expect: 84983e441c3bd26ebaae4aa1f95129e5e54670f1 # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... -> digest: 34aa973cd4c4daa4f61eeb2bdbad27316534016f -> expect: 34aa973cd4c4daa4f61eeb2bdbad27316534016f
Kotlin
// 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()
}
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Lasso
cipher_digest('Rosetta Code', -digest='SHA1',-hex=true)
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Liberty BASIC
'--------------------------------------------------------------------------------
' 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
- Output:
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
Lingo
crypto = xtra("Crypto").new()
put crypto.cx_sha1_string("Rosetta Code")
- Output:
-- "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"
LiveCode
command shaRosettaCode
local shex, sha1
put sha1Digest("Rosetta Code") into sha1
get binaryDecode("H*",sha1,shex)
put shex
end shaRosettaCode
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
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
- Output:
SHA-1("Rosetta code") = b18c883f4da750164b5af362ea9b9f27f90904b4 SHA-1("Rosetta Code") = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Maple
with(StringTools):
Hash("Ars longa, vita brevis",method="SHA1");
# "e640d285242886eb96ab80cbf858389b3df52f43"
Mathematica/Wolfram Language
Hash["Rosetta code","SHA1","HexString"]
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
min
"Rosetta Code" sha1 puts!
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Neko
SHA-1 was added in Neko 2.2.
/**
SHA-1 in Neko
Tectonics:
nekoc SHA-1.neko
neko SHA-1
*/
var SHA1 = $loader.loadprim("std@make_sha1", 3);
var base_encode = $loader.loadprim("std@base_encode", 2);
var msg = "Rosetta Code";
var result = SHA1(msg, 0, $ssize(msg));
/* Output in lowercase hex */
$print(base_encode(result, "0123456789abcdef"));
- Output:
prompt$ nekoc SHA-1.neko prompt$ neko SHA-1.n 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5prompt$
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.
/* 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
- Output:
<Message>Rosetta Code</Message> <SHA-1>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</SHA-1> <Verify>48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</Verify> SHA-1 Confirmed
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")
Nim
Nim standard library provides the module “std/sha1” to compute SHA1 digests.
import std/sha1
echo secureHash("Rosetta Code")
- Output:
48C98F7E5A6E736D790AB740DFC3F51A61ABE2B5
Oberon-2
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.
- Output:
SHA1: 48C98F7E 5A6E736D 790AB740 DFC3F51A 61ABE2B5
OCaml
Using the library ocaml-sha
in the interactive loop:
$ ocaml -I +sha sha1.cma
Objective Caml version 3.12.1
# Sha1.to_hex (Sha1.string "Rosetta Code") ;;
- : string = "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"
Octave
Normally SHA-1 is available in the general package.
sprintf("%02x", SHA1(+"Rosetta Code"(:)))
- Output:
ans = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
PARI/GP
It works on Linux systems.
sha1(s)=extern("echo \"Str(`echo -n '"Str(s)"'|sha1sum|cut -d' ' -f1`)\"")
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
program RosettaSha1;
uses
sha1;
var
d: TSHA1Digest;
begin
d:=SHA1String('Rosetta Code');
WriteLn(SHA1Print(d));
end.
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Perl
use Digest::SHA qw(sha1_hex);
print sha1_hex('Rosetta Code'), "\n";
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
The same in OO manner
use Digest::SHA;
my $sha1 = Digest::SHA->new(1);
$sha1->add('Rosetta Code');
print $sha1->hexdigest, "\n";
Phix
-- -- demo\rosetta\sha1.exw -- ===================== -- -- NB no longer considered secure. Non-optimised. -- function uint32(atom v) return and_bitsu(v,#FFFFFFFF) 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")
- Output:
"48c98f7e 5a6e736d 790ab740 dfc3f51a 61abe2b5"
PHP
<?php
$string = 'Rosetta Code';
echo sha1( $string ), "\n";
?>
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
PicoLisp
Library and implementation.
(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)
Pike
string input = "Rosetta Code";
string out = Crypto.SHA1.hash(input);
write( String.string2hex(out) +"\n");
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
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)
}
taken from Stackoverflow with a little modification
Prolog
SWI-Prolog has SHA1 hashing as the default in its sha_hash
function.
:- use_module(library(sha)).
sha_hex(Str,Hex):-
sha_hash(Str, Hash, []),
hash_atom(Hash, Hex).
?- sha_hex("Rosetta Code",Hex).
Hex = '48c98f7e5a6e736d790ab740dfc3f51a61abe2b5'.
PureBasic
PB Version 5.40
a$="Rosetta Code"
UseSHA1Fingerprint() : b$=StringFingerprint(a$, #PB_Cipher_SHA1)
OpenConsole()
Print("[SHA1] Text: "+a$+" ==> "+b$)
Input()
- Output:
[SHA1] Text: Rosetta Code ==> 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Python
import hashlib
h = hashlib.sha1()
h.update(bytes("Ars longa, vita brevis", encoding="ASCII"))
h.hexdigest()
# "e640d285242886eb96ab80cbf858389b3df52f43"
R
library(digest)
input <- "Rosetta Code"
cat(digest(input, algo = "sha1", serialize = FALSE), "\n")
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Racket
With the built-in file/sha1 library:
#lang racket
(require file/sha1)
(sha1 (open-input-string "Rosetta Code"))
With the faster openssl/sha1 library (requires OpenSSL to be installed):
#lang racket
(require openssl/sha1)
(sha1 (open-input-string "Rosetta Code"))
Raku
(formerly Perl 6)
Pure Raku
A pure Raku implementation that closely follows the description of SHA-1 in FIPS 180-1. Slow.
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';
- 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.
use Digest::SHA1::Native;
# use sha1-hex() if you want a hex string
say sha1($_), " $_" for
'abc',
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq',
'Rosetta Code',
'Ars longa, vita brevis'
;
- 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
# Project : SHA-1
load "stdlib.ring"
str = "Rosetta Code"
see "String: " + str + nl
see "SHA-1: "
see sha1(str) + nl
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.
require 'digest'
puts Digest::SHA1.hexdigest('Rosetta Code')
Second: Use 'openssl' from Ruby's standard library.
require 'openssl'
puts OpenSSL::Digest::SHA1.hexdigest('Rosetta Code')
Third: Reimplement SHA-1 in 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
- Output:
abc: a9993e364706816aba3e25717850c26c9cd0d89d abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq: 84983e441c3bd26ebaae4aa1f95129e5e54670f1 Rosetta Code: 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Rust
Using sha1 crate: https://docs.rs/sha1/0.6.0/sha1/
use sha1::Sha1;
fn main() {
let mut hash_msg = Sha1::new();
hash_msg.update(b"Rosetta Code");
println!("{}", hash_msg.digest().to_string());
}
Output
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
S-lang
Support for MD5 and SHA-1 are included in the standard "chksum" library:
require("chksum");
print(sha1sum("Rosetta Code"));
- Output:
"48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"
Scala
The solution to this task would be a small modification to MD5 (replacing "MD5" with "SHA-1" as noted here).
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"))
}
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
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)))))))))
- Output:
(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
Seed7
$ include "seed7_05.s7i";
include "msgdigest.s7i";
const proc: main is func
begin
writeln(hex(sha1("Rosetta Code")));
end func;
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Sidef
var sha = frequire('Digest::SHA');
say sha.sha1_hex('Rosetta Code');
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Smalltalk
PackageLoader fileInPackage: 'Digest'.
(SHA1 hexDigestOf: 'Rosetta Code') displayNl.
(SHA1Stream hashValueOf:'Rosetta Code')
Tcl
package require sha1
puts [sha1::sha1 "Rosetta Code"]
- 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
$ echo -n 'ASCII string' | sha1
9e9aeefe5563845ec5c42c5630842048c0fc261b
$ echo -n 'ASCII string' | openssl sha1 | sed 's/.*= //'
9e9aeefe5563845ec5c42c5630842048c0fc261b
V (Vlang)
import crypto.sha1
fn main() {
println("${sha1.hexhash('Rosetta Code')}")//Rosetta code
mut h := sha1.new()
h.write('Rosetta Code'.bytes()) ?
println('${h.checksum().map(it.hex()).join('')}')
}
- Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Wren
import "./crypto" for Sha1
import "./fmt" for Fmt
var strings = [
"",
"a",
"abc",
"message digest",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
"The quick brown fox jumps over the lazy dog",
"The quick brown fox jumps over the lazy cog",
"Rosetta Code"
]
for (s in strings) {
var hash = Sha1.digest(s)
Fmt.print("$s <== '$0s'", hash, s)
}
- Output:
da39a3ee5e6b4b0d3255bfef95601890afd80709 <== '' 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 <== 'a' a9993e364706816aba3e25717850c26c9cd0d89d <== 'abc' c12252ceda8be8994d5fa0290a47231c1d16aae3 <== 'message digest' 32d10c7b8cf96570ca04ce37f2a19d84240d3a89 <== 'abcdefghijklmnopqrstuvwxyz' 761c457bf73b14d27e9e9265c46f4b4dda11f940 <== 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' 50abf5706a150990a08b2c5ea40fa0e585554732 <== '12345678901234567890123456789012345678901234567890123456789012345678901234567890' 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12 <== 'The quick brown fox jumps over the lazy dog' de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3 <== 'The quick brown fox jumps over the lazy cog' 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 <== 'Rosetta Code'
zkl
Using zklMsgHash so. Can return the hash as a string of hex digits or bytes, can hash the hash N times.
$ 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
- 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
- Delphi
- System.SysUtils
- DCPsha1
- DWScript
- Elixir
- Emacs Lisp
- Erlang
- F Sharp
- Factor
- Fortran
- FreeBASIC
- Frink
- Genie
- Go
- Halon
- Hare
- Haskell
- Haxe
- J
- Java
- Jsish
- Julia
- Kotlin
- Lasso
- Liberty BASIC
- Lingo
- Crypto Xtra
- LiveCode
- Lua
- Sha1
- Maple
- Mathematica
- Wolfram Language
- Min
- Neko
- NetRexx
- NewLISP
- Nim
- Oberon-2
- Crypto
- OCaml
- Octave
- PARI/GP
- Pascal
- Perl
- Phix
- PHP
- PicoLisp
- Pike
- PowerShell
- Prolog
- PureBasic
- Python
- R
- Racket
- Raku
- Ring
- Ruby
- Rust
- S-lang
- Scala
- Scheme
- Seed7
- Sidef
- Smalltalk
- Tcl
- Tcllib
- UNIX Shell
- V (Vlang)
- Wren
- Wren-crypto
- Wren-fmt
- Zkl
- Lilypond/Omit
- TUSCRIPT/Omit