mirage / digestif

Simple hash algorithms in OCaml

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Safe to_hex and of_hex function

dinosaure opened this issue · comments

let to_hex hash =
  let chr x = match x with
      | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 -> Char.chr (0x30 + x)
      | _ -> Char.chr (87 + x) in
  String.init (D.digest_size * 2)
  (fun i ->
    let ch = Char.code hash.[i / 2] in
    let shift = ((i land 1) lxor 1) lsl 2 in (* even: 0; odd: 4*)
    chr ((ch lsr shift) land 0x0f)
  )

and

let of_hex hex =
  let code x = match x with
      | '0' .. '9' -> Char.code x - 48
      | 'A' .. 'F' -> Char.code x - 55
      | 'a' .. 'z' -> Char.code x - 87
      | _ -> invalid_arg "of_hex" in
  let decode_char ch1 ch2 = Char.chr ((code ch1 lsl 4) lor (code ch2)) in
  let offset = ref 0 in
  let rec next have_first idx =
    if !offset + idx >= String.length v then
      '\x00' (* right-pad with 0x00 *)
    else match hex.[!offset + idx] with
    | ' ' | '\t' | '\r' | '\n' ->
      incr offset; next has_first idx
    | ch2 when has_first -> ch2
    | ch1 ->
      incr offset ;
      let ch2 = next true idx in
      if ch2 <> '\x00' then
        decode_char ch1 ch2
      else
        invalid_arg "of_hex: odd number of hex characters"
  in
  String.init D.digest_size (next false)