RIPEMD-160: Difference between revisions
m (→{{header|Go}}: update sub-repo url) |
(Add Perl) |
||
Line 115: | Line 115: | ||
Output: |
Output: |
||
<pre>B3BE159860842CEBAA7174C8FFF0AA9E50A5199F</pre> |
<pre>B3BE159860842CEBAA7174C8FFF0AA9E50A5199F</pre> |
||
=={{header|Perl}}== |
|||
<lang perl>use Crypt::RIPEMD160; |
|||
say unpack "H*", Crypt::RIPEMD160->hash("Rosetta Code");</lang> |
|||
{{out}} |
|||
<pre>b3be159860842cebaa7174c8fff0aa9e50a5199f</pre> |
|||
The [https://metacpan.org/release/CryptX CryptX] module also implements RIPEMD-160 along with the 128-, 256-, and 320-bit variants, as well many many other hashes. This gives identical output as above as expected. |
|||
<lang perl>use Crypt::Digest::RIPEMD160 qw/ripemd160_hex/; |
|||
say ripemd160_hex("Rosetta Code")</lang> |
|||
=={{header|Perl 6}}== |
=={{header|Perl 6}}== |
Revision as of 22:04, 7 November 2014
You are encouraged to solve this task according to the task description, using any language you may know.
RIPEMD-160 is another hash function; it computes a 160-bit message digest.
There is a RIPEMD-160 home page, with test vectors and pseudocode for RIPEMD-160. For padding the message, RIPEMD-160 acts like MD4 (RFC 1320).
Find the RIPEMD-160 message digest of a string of octets. Use the ASCII encoded string “Rosetta Code”. You may either call an RIPEMD-160 library, or implement RIPEMD-160 in your language.
Clojure
<lang clojure>(use 'pandect.core) (ripemd160 "Rosetta Code")</lang>
- Output:
"b3be159860842cebaa7174c8fff0aa9e50a5199f"
Common Lisp
<lang lisp>(ql:quickload 'ironclad) (defun string-to-ripemd-160 (str)
"Return the RIPEMD-160 digest of the given ASCII string." (ironclad:byte-array-to-hex-string (ironclad:digest-sequence :ripemd-160 (ironclad:ascii-string-to-byte-array str)))
(string-to-ripemd-160 "Rosetta Code")</lang>
- Output:
"b3be159860842cebaa7174c8fff0aa9e50a5199f"
D
<lang d>void main() {
import std.stdio, std.digest.ripemd;
writefln("%(%02x%)", "Rosetta Code".ripemd160Of);
}</lang>
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f
Go
<lang go>package main
import (
"golang.org/x/crypto/ripemd160" "fmt"
)
func main() {
h := ripemd160.New() h.Write([]byte("Rosetta Code")) fmt.Printf("%x\n", h.Sum(nil))
}</lang>
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f
Java
<lang java>import org.bouncycastle.crypto.digests.RIPEMD160Digest; import org.bouncycastle.util.encoders.Hex;
public class RosettaRIPEMD160 {
public static void main (String[] argv) throws Exception { byte[] r = "Rosetta Code".getBytes("US-ASCII"); RIPEMD160Digest d = new RIPEMD160Digest(); d.update (r, 0, r.length); byte[] o = new byte[d.getDigestSize()]; d.doFinal (o, 0); Hex.encode (o, System.out); System.out.println(); }
}</lang>
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f
Lasso
<lang lasso> cipher_digest("Rosetta Code", -digest='RIPEMD160', -hex) </lang>
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f
Lua
luarocks install LuaCrypto (see mkottman dot github dot io slash luacrypto; I am getting fed up with reCAPTCHA)
<lang Lua>#!/usr/bin/lua
require "crypto"
print(crypto.digest("ripemd160", "Rosetta Code"))</lang>
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f
Objeck
<lang objeck> class Hash {
function : Main(args : String[]) ~ Nil { in := "Rosetta Code"->ToByteArray(); hash := Encryption.Hash->RIPEMD160(in); hash->ToHexString()->PrintLine(); }
} </lang> Output:
B3BE159860842CEBAA7174C8FFF0AA9E50A5199F
Perl
<lang perl>use Crypt::RIPEMD160; say unpack "H*", Crypt::RIPEMD160->hash("Rosetta Code");</lang>
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f
The CryptX module also implements RIPEMD-160 along with the 128-, 256-, and 320-bit variants, as well many many other hashes. This gives identical output as above as expected. <lang perl>use Crypt::Digest::RIPEMD160 qw/ripemd160_hex/; say ripemd160_hex("Rosetta Code")</lang>
Perl 6
<lang perl6>=for CREDITS Crypto-JS v2.0.0 http:#code.google.com/p/crypto-js/ Copyright (c) 2009, Jeff Mott. All rights reserved.
sub rotl($n, $b) { $n +< $b +| $n +> (32 - $b) } sub prefix:<m^> { +^$^x % 2**32 } sub infix:<m+> { ($^x + $^y) % 2**32 }
constant r1 = <
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 7 4 13 1 10 6 15 3 12 0 9 5 2 14 11 8 3 10 14 4 9 15 8 1 2 7 0 6 13 11 5 12 1 9 11 10 0 8 12 4 13 3 7 15 14 5 6 2 4 0 5 9 7 12 2 10 14 1 3 8 11 6 15 13
>; constant r2 = <
5 14 7 0 9 2 11 4 13 6 15 8 1 10 3 12 6 11 3 7 0 13 5 10 14 15 8 12 4 9 1 2 15 5 1 3 7 14 6 9 11 8 12 2 10 0 4 13 8 6 4 1 3 11 15 0 5 12 2 13 9 7 10 14 12 15 10 4 1 5 8 7 6 2 13 14 0 3 9 11
>; constant s1 = <
11 14 15 12 5 8 7 9 11 13 14 15 6 7 9 8 7 6 8 13 11 9 7 15 7 12 15 9 11 7 13 12 11 13 6 7 14 9 13 15 14 8 13 6 5 12 7 5 11 12 14 15 14 15 9 8 9 14 5 6 8 6 5 12 9 15 5 11 6 8 13 12 5 12 13 14 11 8 5 6
>; constant s2 = <
8 9 9 11 13 15 15 5 7 7 8 11 14 14 12 6 9 13 15 7 12 8 9 11 7 7 12 7 6 15 13 11 9 7 15 11 8 6 6 14 12 13 5 14 13 13 7 5 15 5 8 11 14 14 6 14 6 9 12 9 12 5 15 8 8 5 12 9 12 5 14 6 8 13 6 5 15 13 11 11
>; constant F =
* +^ * +^ *, { ($^x +& $^y) +| (m^$^x +& $^z) }, (* +| m^*) +^ *, { ($^x +& $^z) +| ($^y +& m^$^z) }, * +^ (* +| m^*),
constant K1 = <0x00000000 0x5a827999 0x6ed9eba1 0x8f1bbcdc 0xa953fd4e> »xx» 16; constant K2 = <0x50a28be6 0x5c4dd124 0x6d703ef3 0x7a6d76e9 0x00000000> »xx» 16;
our proto rmd160($) returns Blob {*} multi rmd160(Str $s) { rmd160 $s.encode: 'ascii' } multi rmd160(Blob $data) {
my @b = $data.list, 0x80; push @b, 0 until (8*@b-448) %% 512; my $len = 8 * $data.elems; push @b, gather for ^8 { take $len % 256; $len div= 256 } my @word = gather for @b -> $a, $b, $c, $d { take reduce * *256 + *, $d, $c, $b, $a; } my @h = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0; loop (my $i = 0; $i < @word; $i += 16) { my @X = my @Y = @h; for ^80 -> $j { my $T = rotl( @X[0] m+ F[$j div 16](|@X[1..3]) m+ (@word[$i+r1[$j]] // 0) m+ K1[$j], s1[$j] ) m+ @X[4]; @X = @X[4], $T, @X[1], rotl(@X[2], 10) % 2**32, @X[3]; $T = rotl( @Y[0] m+ F[(79-$j) div 16](|@Y[1..3]) m+ (@word[$i+r2[$j]] // 0) m+ K2[$j], s2[$j] ) m+ @Y[4]; @Y = @Y[4], $T, @Y[1], rotl(@Y[2], 10) % 2**32, @Y[3]; } @h = @h[1..4,^1] Z[m+] @X[2..4,^2] Z[m+] @Y[3..4,^3]; } return Blob.new: gather for @h -> $word is rw { for ^4 { take $word % 256; $word div= 256 } }
}
say rmd160 "Rosetta Code";</lang>
- Output:
Buf:0x<b3 be 15 98 60 84 2c eb aa 71 74 c8 ff f0 aa 9e 50 a5 19 9f>
PicoLisp
<lang PicoLisp>(de *R160-R1 . (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
8 5 14 2 11 7 16 4 13 1 10 6 3 15 12 9 4 11 15 5 10 16 9 2 3 8 1 7 14 12 6 13 2 10 12 11 1 9 13 5 14 4 8 16 15 6 7 3 5 1 6 10 8 13 3 11 15 2 4 9 12 7 16 14 .))
(de *R160-R2 . (6 15 8 1 10 3 12 5 14 7 16 9 2 11 4 13
7 12 4 8 1 14 6 11 15 16 9 13 5 10 2 3 16 6 2 4 8 15 7 10 12 9 13 3 11 1 5 14 9 7 5 2 4 12 16 1 6 13 3 14 10 8 11 15 13 16 11 5 2 6 9 8 7 3 14 15 1 4 10 12 .))
(de *R160-S1 . (11 14 15 12 5 8 7 9 11 13 14 15 6 7 9 8
7 6 8 13 11 9 7 15 7 12 15 9 11 7 13 12 11 13 6 7 14 9 13 15 14 8 13 6 5 12 7 5 11 12 14 15 14 15 9 8 9 14 5 6 8 6 5 12 9 15 5 11 6 8 13 12 5 12 13 14 11 8 5 6 .))
(de *R160-S2 . (8 9 9 11 13 15 15 5 7 7 8 11 14 14 12 6
9 13 15 7 12 8 9 11 7 7 12 7 6 15 13 11 9 7 15 11 8 6 6 14 12 13 5 14 13 13 7 5 15 5 8 11 14 14 6 14 6 9 12 9 12 5 15 8 8 5 12 9 12 5 14 6 8 13 6 5 15 13 11 11 .))
(de mod32 (N)
(& N `(hex "FFFFFFFF")) )
(de not32 (N)
(x| N `(hex "FFFFFFFF")) )
(de add32 @
(mod32 (pass +)) )
(de leftRotate (X C)
(| (mod32 (>> (- C) X)) (>> (- 32 C) X)) )
(de ripemd160 (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 ) (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 (A1 H0 B1 H1 C1 H2 D1 H3 E1 H4 A2 H0 B2 H1 C2 H2 D2 H3 E2 H4 W (make (do 16 (link (apply | (mapcar >> (0 -8 -16 -24) (cut 4 'Str)) ) ) ) ) ) (use (Func1 Func2 Hex1 Hex2) (for I 80 (cond ((>= 16 I) (setq Func1 '(x| B1 C1 D1) Func2 '(x| B2 (| C2 (not32 D2))) Hex1 0 Hex2 `(hex "50A28BE6") ) ) ((>= 32 I) (setq Func1 '(| (& B1 C1) (& (not32 B1) D1)) Func2 '(| (& B2 D2) (& C2 (not32 D2))) Hex1 `(hex "5A827999") Hex2 `(hex "5C4DD124") ) ) ((>= 48 I) (setq Func1 '(x| (| B1 (not32 C1)) D1) Func2 '(x| (| B2 (not32 C2)) D2) Hex1 `(hex "6ED9EBA1") Hex2 `(hex "6D703EF3") ) ) ((>= 64 I) (setq Func1 '(| (& B1 D1) (& C1 (not32 D1))) Func2 '(| (& B2 C2) (& (not32 B2) D2)) Hex1 `(hex "8F1BBCDC") Hex2 `(hex "7A6D76E9") ) ) (T (setq Func1 '(x| B1 (| C1 (not32 D1))) Func2 '(x| B2 C2 D2) Hex1 `(hex "A953FD4E") Hex2 0 ) ) ) (setq Tmp1 (add32 (leftRotate (add32 A1 (eval Func1) (get W (pop '*R160-R1)) Hex1 ) (pop '*R160-S1) ) E1 ) Tmp2 (add32 (leftRotate (add32 A2 (eval Func2) (get W (pop '*R160-R2)) Hex2 ) (pop '*R160-S2) ) E2 ) A1 E1 E1 D1 D1 (leftRotate C1 10) C1 B1 B1 Tmp1 A2 E2 E2 D2 D2 (leftRotate C2 10) C2 B2 B2 Tmp2 ) ) ) (setq Tmp (add32 H1 C1 D2) H1 (add32 H2 D1 E2) H2 (add32 H3 E1 A2) H3 (add32 H4 A1 B2) H4 (add32 H0 B1 C2) H0 Tmp ) ) ) (make (for N (list H0 H1 H2 H3 H4) (do 4 (link (& N 255)) (setq N (>> 8 N)) ) ) ) ) )
(let Str "Rosetta Code"
(println (pack (mapcar '((B) (pad 2 (hex B))) (ripemd160 Str) ) ) ) (println (pack (mapcar '((B) (pad 2 (hex B))) (native "libcrypto.so" "RIPEMD160" '(B . 20) Str (length Str) '(NIL (20)) ) ) ) ) )
(bye)</lang>
Python
<lang python>Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32 Type "copyright", "credits" or "license()" for more information. >>> import hashlib >>> h = hashlib.new('ripemd160') >>> h.update(b"Rosetta Code") >>> h.hexdigest() 'b3be159860842cebaa7174c8fff0aa9e50a5199f' >>> </lang>
Racket
<lang racket>
- lang racket
(require (planet soegaard/digest:1:2/digest)) (ripemd160 #"Rosetta Code") </lang> Output: <lang racket> "b3be159860842cebaa7174c8fff0aa9e50a5199f" </lang>
Ruby
Use 'digest' from Ruby's standard library.
<lang ruby>require 'digest' puts Digest::RMD160.hexdigest('Rosetta Code')</lang>
Use 'openssl' from Ruby's standard library.
<lang ruby>require 'openssl' puts OpenSSL::Digest::RIPEMD160.hexdigest('Rosetta Code')</lang>
Implement RIPEMD-160 in Ruby.
<lang ruby>require 'stringio'
module RMD160
# functions and constants MASK = (1 << 32) - 1 F = [ proc {|x, y, z| x ^ y ^ z}, proc {|x, y, z| (x & y) | (x.^(MASK) & z)}, proc {|x, y, z| (x | y.^(MASK)) ^ z}, proc {|x, y, z| (x & z) | (y & z.^(MASK))}, proc {|x, y, z| x ^ (y | z.^(MASK))}, ].freeze K = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e] KK = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000] R = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13] RR = [5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11] S = [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6] SS = [8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11]
module_function
def rol(value, shift) (value << shift).&(MASK) | (value.&(MASK) >> (32 - shift)) end
# Calculates RIPEMD-160 message digest of _string_. Returns binary # digest. For hexadecimal digest, use # +*RMD160.rmd160(string).unpack('H*')+. def rmd160(string) # initial hash h0 = 0x67452301 h1 = 0xefcdab89 h2 = 0x98badcfe h3 = 0x10325476 h4 = 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) or ( # Work around a bug in Rubinius 1.2.4. At eof, # MRI and JRuby already replace block with "". block.replace("") )
# Unpack block into 32-bit words "V". case len = block.length when 64 # Unpack 16 words. x = block.unpack("V16") when 56..63 # Second-last block: append padding, unpack 16 words. block.concat("\x80"); term = true block.concat("\0" * (63 - len)) x = block.unpack("V16") when 0..55 # Last block: append padding, unpack 14 words. block.concat(term ? "\0" : "\x80") block.concat("\0" * (55 - len)) x = block.unpack("V14")
# Append bit length, 2 words. bit_len = string.length << 3 x.push(bit_len & MASK, bit_len >> 32) last = true else fail "impossible" end
# Process this block. a, b, c, d, e = h0, h1, h2, h3, h4 aa, bb, cc, dd, ee = h0, h1, h2, h3, h4 j = 0 5.times {|ro| f, ff = F[ro], F[4 - ro] k, kk = K[ro], KK[ro] 16.times { a, e, d, c, b = e, d, rol(c, 10), b, rol(a + f[b, c, d] + x[R[j]] + k, S[j]) + e aa, ee, dd, cc, bb = ee, dd, rol(cc, 10), bb, rol(aa + ff[bb, cc, dd] + x[RR[j]] + kk, SS[j]) + ee j += 1 } } h0, h1, h2, h3, h4 = (h1 + c + dd) & MASK, (h2 + d + ee) & MASK, (h3 + e + aa) & MASK, (h4 + a + bb) & MASK, (h0 + b + cc) & MASK end # until last
[h0, h1, h2, h3, h4].pack("V5") end
end
if __FILE__ == $0
# Print an example RIPEMD-160 digest. str = 'Rosetta Code' printf "%s:\n %s\n", str, *RMD160.rmd160(str).unpack('H*')
end</lang>
Scala
<lang Scala>import org.bouncycastle.crypto.digests.RIPEMD160Digest
object RosettaRIPEMD160 extends App {
val (raw, messageDigest) = ("Rosetta Code".getBytes("US-ASCII"), new RIPEMD160Digest()) messageDigest.update(raw, 0, raw.length) val out = Array.fill[Byte](messageDigest.getDigestSize())(0) messageDigest.doFinal(out, 0) assert(out.map("%02x".format(_)).mkString == "b3be159860842cebaa7174c8fff0aa9e50a5199f")
}</lang>
Swift
Full implementation on Github. A single block is processed as shown below.
To apply RIPEMD to "Rosetta Code" takes a single block. The message itself is put in the first 3 words. It's followed by 0x80 in the fourth word.The last two UInt32's (words) are used to specify the length of the message in bits.
Everything is in little endian, so "Rose" becomes "esoR" becomes 0x65_73_6f_52
<lang swift> var block = Block() let message:[UInt32] = [ 0x65_73_6f_52, 0x20_61_74_74, 0x65_64_6f_43, 0x00_00_00_80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0 ] block.compress(message) let digest = NSString(format: "%2x%2x%2x%2x%2x", UInt32(bigEndian: block.hash[0]), UInt32(bigEndian: block.hash[1]),UInt32(bigEndian: block.hash[2]), UInt32(bigEndian: block.hash[3]), UInt32(bigEndian: block.hash[4])) println(digest) </lang>
<lang swift>
struct Block { init() {} var message: [UInt32] = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] // Initial values var h₀: UInt32 = 0x67452301 var h₁: UInt32 = 0xEFCDAB89 var h₂: UInt32 = 0x98BADCFE var h₃: UInt32 = 0x10325476 var h₄: UInt32 = 0xC3D2E1F0 var hash: [UInt32] { return [h₀, h₁, h₂, h₃, h₄] } mutating func compress (message: [UInt32]) -> () { assert(countElements(message) == 16, "Wrong message size") var Aᴸ = h₀ var Bᴸ = h₁ var Cᴸ = h₂ var Dᴸ = h₃ var Eᴸ = h₄ var Aᴿ = h₀ var Bᴿ = h₁ var Cᴿ = h₂ var Dᴿ = h₃ var Eᴿ = h₄ for j in 0...79 { // Left side let wordᴸ = message[r.Left[j]] let functionᴸ = f(j) let Tᴸ: UInt32 = ((Aᴸ &+ functionᴸ(Bᴸ,Cᴸ,Dᴸ) &+ wordᴸ &+ K.Left[j]) ~<< s.Left[j]) &+ Eᴸ Aᴸ = Eᴸ Eᴸ = Dᴸ Dᴸ = Cᴸ ~<< 10 Cᴸ = Bᴸ Bᴸ = Tᴸ // Right side let wordᴿ = message[r.Right[j]] let functionᴿ = f(79 - j) let Tᴿ: UInt32 = ((Aᴿ &+ functionᴿ(Bᴿ,Cᴿ,Dᴿ) &+ wordᴿ &+ K.Right[j]) ~<< s.Right[j]) &+ Eᴿ Aᴿ = Eᴿ Eᴿ = Dᴿ Dᴿ = Cᴿ ~<< 10 Cᴿ = Bᴿ Bᴿ = Tᴿ } let T = h₁ &+ Cᴸ &+ Dᴿ h₁ = h₂ &+ Dᴸ &+ Eᴿ h₂ = h₃ &+ Eᴸ &+ Aᴿ h₃ = h₄ &+ Aᴸ &+ Bᴿ h₄ = h₀ &+ Bᴸ &+ Cᴿ h₀ = T } func f (j: Int) -> ((UInt32, UInt32, UInt32) -> UInt32) { switch j { case let index where j < 0: assert("Invalid j") return {(_, _, _) in 0 } case let index where j <= 15: return {(x, y, z) in x ^ y ^ z } case let index where j <= 31: return {(x, y, z) in (x & y) | (~x & z) } case let index where j <= 47: return {(x, y, z) in (x | ~y) ^ z } case let index where j <= 63: return {(x, y, z) in (x & z) | (y & ~z) } case let index where j <= 79: return {(x, y, z) in x ^ (y | ~z) } default: assert("Invalid j") return {(_, _, _) in 0 } } } enum K { case Left, Right subscript(j: Int) -> UInt32 { switch index { case let index where j < 0: assert("Invalid j") return 0 case let index where j <= 15: return self == .Left ? 0x00000000 : 0x50A28BE6 case let index where j <= 31: return self == .Left ? 0x5A827999 : 0x5C4DD124 case let index where j <= 47: return self == .Left ? 0x6ED9EBA1 : 0x6D703EF3 case let index where j <= 63: return self == .Left ? 0x8F1BBCDC : 0x7A6D76E9 case let index where j <= 79: return self == .Left ? 0xA953FD4E : 0x00000000 default: assert("Invalid j") return 0 } } } enum r { case Left, Right subscript (j: Int) -> Int { switch j { case let index where j < 0: assert("Invalid j") return 0 case let index where j <= 15: if self == .Left { return index } else { return [5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12][index] } case let index where j <= 31: if self == .Left { return [ 7, 4,13, 1,10, 6,15, 3,12, 0, 9, 5, 2,14,11, 8][index - 16] } else { return [ 6,11, 3, 7, 0,13, 5,10,14,15, 8,12, 4, 9, 1, 2][index - 16] } case let index where j <= 47: if self == .Left { return [3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12][index - 32] } else { return [15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13][index - 32] } case let index where j <= 63: if self == .Left { return [1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2][index - 48] } else { return [8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14][index - 48] } case let index where j <= 79: if self == .Left { return [ 4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13][index - 64] } else { return [12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11][index - 64] }
default: assert("Invalid j") return 0 } }
} enum s { case Left, Right subscript(j: Int) -> Int { switch index { case let index where j < 0: assert("Invalid j") return 0 case let index where j <= 15: return (self == .Left ? [11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8] : [8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6])[j] case let index where j <= 31: return (self == .Left ? [7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12] : [9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11])[j - 16] case let index where j <= 47: return (self == .Left ? [11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5] : [9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5])[j - 32] case let index where j <= 63: return (self == .Left ? [11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12] : [15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8])[j - 48] case let index where j <= 79: return (self == .Left ? [9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6] : [8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11])[j - 64] default: assert("Invalid j") return 0 } }
} }
</lang>
Tcl
<lang tcl>package require ripemd160
puts [ripemd::ripemd160 -hex "Rosetta Code"]</lang>
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f
zkl
Uses shared library zklMsgHash.so <lang zkl>var MsgHash=Import("zklMsgHash"); MsgHash.RIPEMD160("Rosetta Code")</lang>
- Output:
b3be159860842cebaa7174c8fff0aa9e50a5199f