SHA-1
You are encouraged to solve this task according to the task description, using any language you may know.
SHA-1 or SHA1 is a one-way hash function; it computes a 160-bit message digest. SHA-1 often appears in security protocols; for example, many HTTPS websites use RSA with SHA-1 to secure their connections. BitTorrent uses SHA-1 to verify downloads. Git and Mercurial use SHA-1 digests to identify commits.
A US government standard, FIPS 180-1, defines SHA-1.
Find the SHA-1 message digest for a string of octets. You may either call a SHA-1 library, or implement SHA-1 in your language. Both approaches interest Rosetta Code.
Ada
<lang Ada>with Ada.Text_IO; with GNAT.SHA1;
procedure Main is begin
Ada.Text_IO.Put_Line ("SHA1 (""Rosetta Code"") = " & GNAT.SHA1.Digest ("Rosetta Code"));
end Main;</lang>
Output:
SHA1 ("Rosetta Code") = 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
C#
Tests the built-in SHA1CryptoServiceProvider: <lang csharp>using System; using System.Security.Cryptography; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace RosettaCode.SHA1 {
[TestClass] public class SHA1CryptoServiceProviderTest { [TestMethod] public void TestComputeHash() { var input = new UTF8Encoding().GetBytes("Rosetta Code"); var output = new SHA1CryptoServiceProvider().ComputeHash(input); Assert.AreEqual( "48-C9-8F-7E-5A-6E-73-6D-79-0A-B7-40-DF-C3-F5-1A-61-AB-E2-B5", BitConverter.ToString(output)); } }
}</lang>
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.)
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.
Go
<lang go>package main
import (
"crypto/sha1" "fmt"
)
func main() {
h := sha1.New() h.Write([]byte("Rosetta Code")) fmt.Printf("%x\n", h.Sum(nil))
}</lang> Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
Java
The solution to this task would be a small modification to MD5 (replacing "MD5" with "SHA-1" as noted here).
Mathematica
<lang Mathematica>IntegerString[Hash["Rosetta Code", "SHA1"], 16]
-> 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5</lang>
OCaml
Using the library ocaml-sha
in the interactive loop:
<lang ocaml>$ ocaml -I +sha sha1.cma
Objective Caml version 3.12.1
- Sha1.to_hex (Sha1.string "Rosetta Code") ;;
- : string = "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"</lang>
Ruby
These programs print the SHA-1 of 'Rosetta Code', which is 48c98f7e5a6e736d790ab740dfc3f51a61abe2b5.
First: Use 'digest' from Ruby's standard library. <lang ruby>require 'digest' puts Digest::SHA1.hexdigest('Rosetta Code')</lang>
Second: Use 'openssl' from Ruby's standard library.
<lang ruby>require 'openssl' puts OpenSSL::Digest::SHA1.hexdigest('Rosetta Code')</lang>
Third: Reimplement SHA-1 in Ruby. <lang ruby>require 'stringio'
- Calculates SHA-1 message digest of _string_. Returns digest as
- binary string.
- --
- This is a simple, pure-Ruby implementation of SHA-1, following
- the algorithm in FIPS 180-1.
- ++
def sha1(string)
# functions and constants mask = (1 << 32) - 1 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]
io = StringIO.new(string) block = "" term = false # appended "\x80" in second-last block? last = false # last block? 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. (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[0..4] t = 0 (0..3).each {|i| 20.times { temp = (s[5, a] + f[i][b, c, d] + e + w[t] + k[i]) & mask e = d; d = c; c = s[30, b]; b = a; a = temp t += 1}}
h[0] = (h[0] + a) & mask h[1] = (h[1] + b) & mask h[2] = (h[2] + c) & mask h[3] = (h[3] + d) & mask h[4] = (h[4] + e) & mask end
h.pack("N5")
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
# 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, hexencode(sha1 s)) }
end</lang>
Tcl
<lang tcl>package require sha1 puts [sha1::sha1 "Rosetta Code"]</lang> Output:
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
It should be noted that the sha1
package is actually a façade that uses an efficient implementation in C if one is available, or a pure Tcl version otherwise.
UNIX Shell
<lang bash>$ echo -n 'ASCII string' | sha1 9e9aeefe5563845ec5c42c5630842048c0fc261b</lang>
<lang bash>$ echo -n 'ASCII string' | openssl sha1 | sed 's/.*= //' 9e9aeefe5563845ec5c42c5630842048c0fc261b</lang>