12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576(**************************************************************************)(* *)(* OCaml *)(* *)(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1996 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* 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. *)(* *)(**************************************************************************)(* Message digest (MD5) *)typet=stringletcompare=String.compareletequal=String.equalexternalunsafe_string:string->int->int->t="caml_md5_string"externalchannel:in_channel->int->t="caml_md5_chan"letstringstr=unsafe_stringstr0(String.lengthstr)letbytesb=string(Bytes.unsafe_to_stringb)letsubstringstrofslen=ifofs<0||len<0||ofs>String.lengthstr-lentheninvalid_arg"Digest.substring"elseunsafe_stringstrofslenletsubbytesbofslen=substring(Bytes.unsafe_to_stringb)ofslenletfilefilename=letic=open_in_binfilenameinmatchchannelic(-1)with|d->close_inic;d|exceptione->close_inic;raiseeletoutputchandigest=output_stringchandigestletinputchan=really_input_stringchan16letchar_hexn=Char.unsafe_chr(n+ifn<10thenChar.code'0'else(Char.code'a'-10))letto_hexd=ifString.lengthd<>16theninvalid_arg"Digest.to_hex";letresult=Bytes.create32infori=0to15doletx=Char.coded.[i]inBytes.unsafe_setresult(i*2)(char_hex(xlsr4));Bytes.unsafe_setresult(i*2+1)(char_hex(xland0x0f));done;Bytes.unsafe_to_stringresultletfrom_hexs=ifString.lengths<>32theninvalid_arg"Digest.from_hex";letdigitc=matchcwith|'0'..'9'->Char.codec-Char.code'0'|'A'..'F'->Char.codec-Char.code'A'+10|'a'..'f'->Char.codec-Char.code'a'+10|_->raise(Invalid_argument"Digest.from_hex")inletbytei=digits.[i]lsl4+digits.[i+1]inletresult=Bytes.create16infori=0to15doBytes.setresulti(Char.chr(byte(2*i)));done;Bytes.unsafe_to_stringresult