1 import Base 2 3 def hex_digit_if(x: U32, small: Bool) -> Char: 4 match small: 5 case True{}: 6 Chr{(48 + x : U32)} 7 case False{}: 8 Chr{(87 + x : U32)} 9 10 def hex_digit(+x: U32) -> Char: 11 hex_digit_if(x, U32.is_lt(x, 10)) 12 13 def hex_word_go(n: Nat, +x: U32, acc: String) -> String: 14 match n: 15 case 0n: 16 acc 17 case 1n+p: 18 hex_word_go(p, U32.shrn(x, 4n), SCon{hex_digit((x .&. 15 : U32)), acc}) 19 20 def hex_byte(+x: U32) -> String: 21 SCon{hex_digit(U32.shrn(x,4n)),SCon{hex_digit(U32.and(x,15)),SNil{}}} 22 23 def hex_word(+x: U32) -> String: 24 hex_byte(U32.and(x,255)) ++ hex_byte(U32.and(U32.shrn(x,8n),255)) ++ hex_byte(U32.and(U32.shrn(x,16n),255)) ++ hex_byte(U32.shrn(x,24n)) 25 26 # Formatting helper consumes eight words; it does not create a digest list. 27 def hex_walk(n: Nat, +index: U32, pair: Array & U32) -> String: 28 match n pair: 29 case 0n Tuple{a,w}: hex_word(w) 30 case 1n+p Tuple{a,w}: hex_word(w) ++ hex_walk(p,U32.inc(index),Array.get(U32,a,index)) 31 32 def hex(a: Array) -> String: 33 hex_walk(7n,1,Array.get(U32,a,0))