experimental hashing with oxcaml
at main 1.5 kB view raw
1let hex_of_bytes bytes = 2 let buf = Buffer.create (Bytes.length bytes * 2) in 3 Bytes.iter 4 (fun c -> Buffer.add_string buf (Printf.sprintf "%02x" (Char.code c))) 5 bytes; 6 Buffer.contents buf 7 8let hash_file filename = 9 try 10 let fd = Unix.openfile filename [ Unix.O_RDONLY ] 0 in 11 let stats = Unix.fstat fd in 12 let file_size = stats.Unix.st_size in 13 14 if file_size = 0 then ( 15 (* Handle empty files *) 16 Unix.close fd; 17 let digest = Oxsha.hash_string "" in 18 Ok (hex_of_bytes digest) 19 ) else ( 20 let mapped = 21 Unix.map_file fd Bigarray.char Bigarray.c_layout false [| file_size |] 22 in 23 let ba = Bigarray.array1_of_genarray mapped in 24 Unix.close fd; 25 26 let digest = Oxsha.hash ba in 27 Ok (hex_of_bytes digest) 28 ) 29 with e -> Error e 30 31let () = 32 if Array.length Sys.argv < 2 then ( 33 Printf.eprintf "Usage: %s FILE [FILE...]\n" Sys.argv.(0); 34 Printf.eprintf "Print SHA256 (256-bit) checksums.\n"; 35 exit 1 36 ); 37 38 let exit_code = ref 0 in 39 40 for i = 1 to Array.length Sys.argv - 1 do 41 let filename = Sys.argv.(i) in 42 match hash_file filename with 43 | Ok hash -> Printf.printf "%s %s\n" hash filename 44 | Error (Sys_error msg) -> 45 Printf.eprintf "%s: %s\n" Sys.argv.(0) msg; 46 exit_code := 1 47 | Error e -> 48 Printf.eprintf "%s: %s: %s\n" Sys.argv.(0) filename 49 (Printexc.to_string e); 50 exit_code := 1 51 done; 52 53 exit !exit_code