123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128(**************************************************************************)(* *)(* Copyright 2016-2019 OCamlPro *)(* *)(* All rights reserved. This file is distributed under the terms of the *)(* GNU Lesser General Public License version 2.1, with the special *)(* exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)typekind=[`MD5|`SHA256|`SHA512]letdefault_kind=`MD5letall_kinds=[`MD5;`SHA256;`SHA512]typet=kind*stringletkind=fstletcontents=snd(* Order by hash strength: MD5 < SHA256 < SHA512 *)letcompare_kindkl=matchk,lwith|`SHA512,`SHA512|`SHA256,`SHA256|`MD5,`MD5->0|`MD5,_|_,`SHA512->-1|`SHA512,_|_,`MD5->1letcompare(k,h)(l,i)=matchcompare_kindklwith|0->String.comparehi|cmp->cmpletequalhh'=comparehh'=0letpfx_sep_char='='letpfx_sep_str=String.make1pfx_sep_charletstring_of_kind=function|`MD5->"md5"|`SHA256->"sha256"|`SHA512->"sha512"letkind_of_strings=matchString.lowercase_asciiswith|"md5"->`MD5|"sha256"->`SHA256|"sha512"->`SHA512|_->invalid_arg"OpamHash.kind_of_string"letis_hex_strlens=String.lengths=len&&OpamStd.String.is_hexsletlen=function|`MD5->32|`SHA256->64|`SHA512->128letvalidkind=is_hex_str(lenkind)letis_nullh=letcount_not_zeroc=function'0'->c|_->succcinOpamStd.String.fold_leftcount_not_zero0(contentsh)<>0letmakekinds=ifvalidkindsthenkind,String.lowercase_asciiselseinvalid_arg("OpamHash.make_"^string_of_kindkind)letmd5=make`MD5letsha256=make`SHA256letsha512=make`SHA512letof_string_opts=tryletkind,s=matchOpamStd.String.cut_atspfx_sep_charwith|None->`MD5,s|Some(skind,s)->kind_of_stringskind,sinifvalidkindsthenSome(kind,String.lowercase_asciis)elseNonewithInvalid_argument_->Noneletof_strings=matchof_string_optswith|Someh->h|None->invalid_arg"OpamHash.of_string"letto_string(kind,s)=String.concatpfx_sep_str[string_of_kindkind;s]letto_jsons=`String(to_strings)letof_json=function|`Strings->of_string_opts|_->Noneletto_path(kind,s)=[string_of_kindkind;String.subs02;s]letsortchecksums=List.sort(funhh'->compareh'h)checksumsletcompute?(kind=default_kind)file=matchkindwith|`MD5->md5(Digest.to_hex(Digest.filefile))|(`SHA256|`SHA512)askind->makekind(OpamSHA.hash_filekindfile)letcompute_from_string?(kind=default_kind)str=matchkindwith|`MD5->md5(Digest.to_hex(Digest.stringstr))|(`SHA256|`SHA512)askind->makekind(OpamSHA.hash_stringkindstr)letcheck_filef(kind,_ash)=compute~kindf=hletmismatchf(kind,_ash)=lethf=compute~kindfinifhf=hthenNoneelseSomehfmoduleO=structtype_t=ttypet=_tletto_string=to_stringletto_json=to_jsonletof_json=of_jsonletcompare=compareendmoduleSet=OpamStd.Set.Make(O)moduleMap=OpamStd.Map.Make(O)