SHA-256: Difference between revisions
(Added BBC BASIC) |
(→{{header|Perl 6}}: adding an exception for non-ASCII strings) |
||
Line 344: | Line 344: | ||
multi sha256(Str $str where all($str.ords) < 128) { |
multi sha256(Str $str where all($str.ords) < 128) { |
||
sha256 $str.encode: 'ascii' |
sha256 $str.encode: 'ascii' |
||
} |
|||
multi sha256(Str $str where any($str.ords) > 127) { |
|||
die "not trying to guess encoding" |
|||
} |
} |
||
multi sha256(Buf $data) { |
multi sha256(Buf $data) { |
Revision as of 09:12, 14 January 2013
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
SHA-256 is the recommended stronger alternative to SHA-1.
Either by using a dedicated library or implementing the algorithm in your language, show that the SHA-256 digest of the string "Rosetta code" is: 764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf
BBC BASIC
Library
<lang bbcbasic> PRINT FNsha256("Rosetta code")
END DEF FNsha256(message$) LOCAL buflen%, buffer%, hcont%, hprov%, hhash%, hash$, i% CALG_SHA_256 = &800C HP_HASHVAL = 2 CRYPT_NEWKEYSET = 8 PROV_RSA_AES = 24 buflen% = 128 DIM buffer% LOCAL buflen%-1 SYS "CryptAcquireContext", ^hcont%, 0, \ \ "Microsoft Enhanced RSA and AES Cryptographic Provider", \ \ PROV_RSA_AES, CRYPT_NEWKEYSET SYS "CryptAcquireContext", ^hprov%, 0, 0, PROV_RSA_AES, 0 SYS "CryptCreateHash", hprov%, CALG_SHA_256, 0, 0, ^hhash% SYS "CryptHashData", hhash%, message$, LEN(message$), 0 SYS "CryptGetHashParam", hhash%, HP_HASHVAL, buffer%, ^buflen%, 0 SYS "CryptDestroyHash", hhash% SYS "CryptReleaseContext", hprov% SYS "CryptReleaseContext", hcont% FOR i% = 0 TO buflen%-1 hash$ += RIGHT$("0" + STR$~buffer%?i%, 2) NEXT = hash$</lang>
Output:
764FAF5C61AC315F1497F9DFA542713965B785E5CC2F707D6468D7D1124CDFCF
Native
<lang bbcbasic> REM SHA-256 calculation by Richard Russell in BBC BASIC for Windows
REM Must run in FLOAT64 mode: *FLOAT64 REM Test message for validation: message$ = "Rosetta code" REM Initialize variables: h0% = &6A09E667 h1% = &BB67AE85 h2% = &3C6EF372 h3% = &A54FF53A h4% = &510E527F h5% = &9B05688C h6% = &1F83D9AB h7% = &5BE0CD19 REM Create table of constants: DIM k%(63) : k%() = \ \ &428A2F98, &71374491, &B5C0FBCF, &E9B5DBA5, &3956C25B, &59F111F1, &923F82A4, &AB1C5ED5, \ \ &D807AA98, &12835B01, &243185BE, &550C7DC3, &72BE5D74, &80DEB1FE, &9BDC06A7, &C19BF174, \ \ &E49B69C1, &EFBE4786, &0FC19DC6, &240CA1CC, &2DE92C6F, &4A7484AA, &5CB0A9DC, &76F988DA, \ \ &983E5152, &A831C66D, &B00327C8, &BF597FC7, &C6E00BF3, &D5A79147, &06CA6351, &14292967, \ \ &27B70A85, &2E1B2138, &4D2C6DFC, &53380D13, &650A7354, &766A0ABB, &81C2C92E, &92722C85, \ \ &A2BFE8A1, &A81A664B, &C24B8B70, &C76C51A3, &D192E819, &D6990624, &F40E3585, &106AA070, \ \ &19A4C116, &1E376C08, &2748774C, &34B0BCB5, &391C0CB3, &4ED8AA4A, &5B9CCA4F, &682E6FF3, \ \ &748F82EE, &78A5636F, &84C87814, &8CC70208, &90BEFFFA, &A4506CEB, &BEF9A3F7, &C67178F2 Length% = 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$(Length% >>> 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%(63) FOR chunk% = 0 TO LEN(message$) DIV 64 - 1 FOR i% = 0 TO 15 w%(i%) = !(!^message$ + 64*chunk% + 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 sixty-four 32-bit words: FOR i% = 16 TO 63 s0% = FNrr(w%(i%-15),7) EOR FNrr(w%(i%-15),18) EOR (w%(i%-15) >>> 3) s1% = FNrr(w%(i%-2),17) EOR FNrr(w%(i%-2),19) EOR (w%(i%-2) >>> 10) w%(i%) = FN32(w%(i%-16) + s0% + w%(i%-7) + s1%) NEXT i% REM Initialize hash value for this chunk: a% = h0% b% = h1% c% = h2% d% = h3% e% = h4% f% = h5% g% = h6% h% = h7% REM Main loop: FOR i% = 0 TO 63 s0% = FNrr(a%,2) EOR FNrr(a%,13) EOR FNrr(a%,22) maj% = (a% AND b%) EOR (a% AND c%) EOR (b% AND c%) t2% = FN32(s0% + maj%) s1% = FNrr(e%,6) EOR FNrr(e%,11) EOR FNrr(e%,25) ch% = (e% AND f%) EOR ((NOT e%) AND g%) t1% = FN32(h% + s1% + ch% + k%(i%) + w%(i%)) h% = g% g% = f% f% = e% e% = FN32(d% + t1%) d% = c% c% = b% b% = a% a% = FN32(t1% + t2%) 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%) h5% = FN32(h5% + f%) h6% = FN32(h6% + g%) h7% = FN32(h7% + h%) NEXT chunk% REM Produce the final hash value (big-endian): hash$ = FNhex(h0%) + " " + FNhex(h1%) + " " + FNhex(h2%) + " " + FNhex(h3%) + \ \ " " + FNhex(h4%) + " " + FNhex(h5%) + " " + FNhex(h6%) + " " + FNhex(h7%) PRINT hash$ END DEF FNrr(A%,I%) = (A% >>> I%) OR (A% << (32-I%)) DEF FNhex(A%) = RIGHT$("0000000"+STR$~A%,8) DEF FN32(n#) WHILE n# > &7FFFFFFF : n# -= 2^32 : ENDWHILE WHILE n# < &80000000 : n# += 2^32 : ENDWHILE = n#</lang>
Output:
764FAF5C 61AC315F 1497F9DF A5427139 65B785E5 CC2F707D 6468D7D1 124CDFCF
C
Requires OpenSSL, compile flag: -lssl
<lang c>#include <stdio.h>
- include <string.h>
- include <openssl/sha.h>
int main (void) { const char *s = "Rosetta code"; unsigned char *d = SHA256(s, strlen(s), 0);
int i; for (i = 0; i < SHA256_DIGEST_LENGTH; i++) printf("%02x", d[i]); putchar('\n');
return 0; }</lang>
C#
<lang csharp>using System; using System.Security.Cryptography; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace RosettaCode.SHA256 {
[TestClass] public class SHA256ManagedTest { [TestMethod] public void TestComputeHash() { var buffer = Encoding.UTF8.GetBytes("Rosetta code"); var hashAlgorithm = new SHA256Managed(); var hash = hashAlgorithm.ComputeHash(buffer); Assert.AreEqual( "76-4F-AF-5C-61-AC-31-5F-14-97-F9-DF-A5-42-71-39-65-B7-85-E5-CC-2F-70-7D-64-68-D7-D1-12-4C-DF-CF", BitConverter.ToString(hash)); } }
}</lang>
Go
<lang go>package main
import (
"crypto/sha256" "fmt" "log"
)
func main() {
h := sha256.New() if _, err := h.Write([]byte("Rosetta code")); err != nil { log.Fatal(err) } fmt.Printf("%x\n", h.Sum(nil))
}</lang>
- Output:
764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf
Java
The solution to this task would be a small modification to MD5 (replacing "MD5" with "SHA-256" as noted here).
Mathematica
<lang>IntegerString[Hash["Rosetta code", "SHA256"], 16]</lang>
Output:
764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf
NetRexx
This solution is basically the same as that for MD5, substituting "SHA-256" for "MD5" as the algorithm to use in the MessageDigest instance. <lang NetRexx>/* NetRexx */ options replace format comments java crossref savelog symbols binary
import java.security.MessageDigest
SHA256('Rosetta code', '764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf')
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method SHA256(messageText, verifyCheck) public static
algorithm = 'SHA-256' digestSum = getDigest(messageText, algorithm)
say '<Message>'messageText'</Message>' say Rexx('<'algorithm'>').right(12) || digestSum'</'algorithm'>' say Rexx('<Verify>').right(12) || verifyCheck'</Verify>' if digestSum == verifyCheck then say algorithm 'Confirmed' else say algorithm 'Failed'
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method getDigest(messageText = Rexx, algorithm = Rexx 'MD5', encoding = Rexx 'UTF-8', lowercase = boolean 1) public static returns Rexx
algorithm = algorithm.upper encoding = encoding.upper
message = String(messageText) messageBytes = byte[] digestBytes = byte[] digestSum = Rexx
do messageBytes = message.getBytes(encoding) md = MessageDigest.getInstance(algorithm) md.update(messageBytes) digestBytes = md.digest
loop b_ = 0 to digestBytes.length - 1 bb = Rexx(digestBytes[b_]).d2x(2) if lowercase then digestSum = digestSum || bb.lower else digestSum = digestSum || bb.upper end b_ catch ex = Exception ex.printStackTrace end return digestSum
</lang> Output:
<Message>Rosetta code</Message> <SHA-256>764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf</SHA-256> <Verify>764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf</Verify> SHA-256 Confirmed
Objeck
<lang Objeck> class ShaHash {
function : Main(args : String[]) ~ Nil { hash:= Encryption.Hash->SHA256("Rosetta code"->ToByteArray()); str := hash->ToHexString()->ToLower(); str->PrintLine(); str->Equals("764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf")->PrintLine(); }
} </lang>
764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf true
Perl
<lang Perl>#!/usr/bin/perl use strict ; use warnings ; use Digest::SHA qw( sha256_hex ) ;
my $digest = sha256_hex my $phrase = "Rosetta code" ; print "SHA-256('$phrase'): $digest\n" ; </lang> Output
SHA-256('Rosetta code'): 764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf
Perl 6
<lang Perl 6>say .list».fmt("%02x").join given sha256 "Rosetta code";
constant primes = grep &is-prime, 2 .. *; sub init(&f) {
map { my $f = $^p.&f; (($f - $f.Int)*2**32).Int }, primes
}
sub infix:<m+> { ($^a + $^b) % 2**32 } sub rotr($n, $b) { $n +> $b +| $n +< (32 - $b) }
proto sha256($) returns Buf {*} multi sha256(Str $str where all($str.ords) < 128) {
sha256 $str.encode: 'ascii'
} multi sha256(Str $str where any($str.ords) > 127) {
die "not trying to guess encoding"
} multi sha256(Buf $data) {
my \K = init(* **(1/3))[^64]; my $l = 8 * my @b = $data.list; push @b, 0x80; push @b, 0 until (8*@b-448) %% 512;
push @b, reverse gather for ^8 { take $l%256; $l div=256 } my @word = gather for @b -> $a, $b, $c, $d { take reduce * *256 + *, $a, $b, $c, $d; }
my @H = init(&sqrt)[^8]; my @w; loop (my $i = 0; $i < @word.elems; $i += 16) { my @h = @H; for ^64 -> $j { @w[$j] = $j < 16 ?? @word[$j + $i] // 0 !! [m+] rotr(@w[$j-15], 7) +^ rotr(@w[$j-15], 18) +^ @w[$j-15] +> 3, @w[$j-7], rotr(@w[$j-2], 17) +^ rotr(@w[$j-2], 19) +^ @w[$j-2] +> 10, @w[$j-16]; my $ch = @h[4] +& @h[5] +^ +^@h[4] % 2**32 +& @h[6]; my $maj = @h[0] +& @h[2] +^ @h[0] +& @h[1] +^ @h[1] +& @h[2]; my $σ0 = [+^] map { rotr @h[0], $_ }, 2, 13, 22; my $σ1 = [+^] map { rotr @h[4], $_ }, 6, 11, 25; my $t1 = [m+] @h[7], $σ1, $ch, K[$j], @w[$j]; my $t2 = $σ0 m+ $maj; @h = $t1 m+ $t2, @h[^3], @h[3] m+ $t1, @h[4..6]; } @H = @H Z[m+] @h; } return Buf.new: map -> $word is rw { reverse gather for ^4 { take $word % 256; $word div= 256 } }, @H;
}</lang>
- Output:
764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf
Python
Python has a standard module for this: <lang python>>>> import hashlib >>> hashlib.sha256( "Rosetta code" ).hexdigest() '764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf' >>> </lang>
Ruby
<lang ruby>require 'digest/sha2' puts Digest::SHA256.hexdigest('Rosetta code')</lang>
Tcl
<lang tcl>package require sha256
puts [sha2::sha256 -hex "Rosetta code"]</lang>
- Output:
764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf