Source file digestif_pp.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
module type B =
sig
type t
val create : int -> t
val iter : (char -> unit) -> t -> unit
val set : t -> int -> char -> unit
val get : t -> int -> char
end
module type D =
sig
val digest_size : int
end
module Make (S : B) (D : D) = struct
let to_hex hash =
let res = S.create (D.digest_size * 2) in
let chr x = match x with
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 -> Char.chr (48 + x)
| _ -> Char.chr (97 + (x - 10))
in
for i = 0 to D.digest_size - 1
do
let v = Char.code (S.get hash i) in
S.set res (i * 2) (chr (v lsr 4));
S.set res (i * 2 + 1) (chr (v land 0x0F));
done;
res
let fold_s f a s =
let r = ref a in
S.iter (fun x -> r := f !r x) s; !r
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
| _ -> raise (Invalid_argument "of_hex")
in
let wsp = function ' ' | '\t' | '\r' | '\n' -> true | _ -> false in
fold_s
(fun (res, i, acc) -> function
| chr when wsp chr -> (res, i, acc)
| chr ->
match acc, code chr with
| None, x -> (res, i, Some (x lsl 4))
| Some y, x -> S.set res i (Char.unsafe_chr (x lor y)); (res, succ i, None))
(S.create D.digest_size, 0, None)
hex
|> function (_, _, Some _) -> raise (Invalid_argument "of_hex")
| (res, i, _) ->
if i = D.digest_size
then res
else (for i = i to D.digest_size - 1 do S.set res i '\000' done; res)
let pp fmt hash =
for i = 0 to D.digest_size - 1
do Format.fprintf fmt "%02x" (Char.code (S.get hash i)) done
end