synacode.pas 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467
  1. {==============================================================================|
  2. | Project : Ararat Synapse | 002.002.003 |
  3. |==============================================================================|
  4. | Content: Coding and decoding support |
  5. |==============================================================================|
  6. | Copyright (c)1999-2013, Lukas Gebauer |
  7. | All rights reserved. |
  8. | |
  9. | Redistribution and use in source and binary forms, with or without |
  10. | modification, are permitted provided that the following conditions are met: |
  11. | |
  12. | Redistributions of source code must retain the above copyright notice, this |
  13. | list of conditions and the following disclaimer. |
  14. | |
  15. | Redistributions in binary form must reproduce the above copyright notice, |
  16. | this list of conditions and the following disclaimer in the documentation |
  17. | and/or other materials provided with the distribution. |
  18. | |
  19. | Neither the name of Lukas Gebauer nor the names of its contributors may |
  20. | be used to endorse or promote products derived from this software without |
  21. | specific prior written permission. |
  22. | |
  23. | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
  24. | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
  25. | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
  26. | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR |
  27. | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
  28. | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
  29. | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
  30. | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
  31. | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
  32. | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
  33. | DAMAGE. |
  34. |==============================================================================|
  35. | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
  36. | Portions created by Lukas Gebauer are Copyright (c)2000-2013. |
  37. | All Rights Reserved. |
  38. |==============================================================================|
  39. | Contributor(s): |
  40. |==============================================================================|
  41. | History: see HISTORY.HTM from distribution package |
  42. | (Found at URL: http://www.ararat.cz/synapse/) |
  43. |==============================================================================}
  44. {:@abstract(Various encoding and decoding support)}
  45. {$IFDEF FPC}
  46. {$MODE DELPHI}
  47. {$ENDIF}
  48. {$Q-}
  49. {$R-}
  50. {$H+}
  51. {$TYPEDADDRESS OFF}
  52. {$IFDEF CIL}
  53. {$DEFINE SYNACODE_NATIVE}
  54. {$ENDIF}
  55. {$IFDEF FPC_BIG_ENDIAN}
  56. {$DEFINE SYNACODE_NATIVE}
  57. {$ENDIF}
  58. {$IFDEF UNICODE}
  59. {$WARN IMPLICIT_STRING_CAST OFF}
  60. {$WARN IMPLICIT_STRING_CAST_LOSS OFF}
  61. {$WARN SUSPICIOUS_TYPECAST OFF}
  62. {$ENDIF}
  63. unit synacode;
  64. interface
  65. uses
  66. SysUtils;
  67. type
  68. TSpecials = set of AnsiChar;
  69. const
  70. SpecialChar: TSpecials =
  71. ['=', '(', ')', '[', ']', '<', '>', ':', ';', ',', '@', '/', '?', '\',
  72. '"', '_'];
  73. NonAsciiChar: TSpecials =
  74. [#0..#31, #127..#255];
  75. URLFullSpecialChar: TSpecials =
  76. [';', '/', '?', ':', '@', '=', '&', '#', '+'];
  77. URLSpecialChar: TSpecials =
  78. [#$00..#$20, '<', '>', '"', '%', '{', '}', '|', '\', '^', '[', ']', '`', #$7F..#$FF];
  79. TableBase64 =
  80. 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  81. TableBase64mod =
  82. 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,=';
  83. TableUU =
  84. '`!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';
  85. TableXX =
  86. '+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  87. ReTablebase64 =
  88. #$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$3E +#$40
  89. +#$40 +#$40 +#$3F +#$34 +#$35 +#$36 +#$37 +#$38 +#$39 +#$3A +#$3B +#$3C
  90. +#$3D +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$00 +#$01 +#$02 +#$03
  91. +#$04 +#$05 +#$06 +#$07 +#$08 +#$09 +#$0A +#$0B +#$0C +#$0D +#$0E +#$0F
  92. +#$10 +#$11 +#$12 +#$13 +#$14 +#$15 +#$16 +#$17 +#$18 +#$19 +#$40 +#$40
  93. +#$40 +#$40 +#$40 +#$40 +#$1A +#$1B +#$1C +#$1D +#$1E +#$1F +#$20 +#$21
  94. +#$22 +#$23 +#$24 +#$25 +#$26 +#$27 +#$28 +#$29 +#$2A +#$2B +#$2C +#$2D
  95. +#$2E +#$2F +#$30 +#$31 +#$32 +#$33 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40;
  96. ReTableUU =
  97. #$01 +#$02 +#$03 +#$04 +#$05 +#$06 +#$07 +#$08 +#$09 +#$0A +#$0B +#$0C
  98. +#$0D +#$0E +#$0F +#$10 +#$11 +#$12 +#$13 +#$14 +#$15 +#$16 +#$17 +#$18
  99. +#$19 +#$1A +#$1B +#$1C +#$1D +#$1E +#$1F +#$20 +#$21 +#$22 +#$23 +#$24
  100. +#$25 +#$26 +#$27 +#$28 +#$29 +#$2A +#$2B +#$2C +#$2D +#$2E +#$2F +#$30
  101. +#$31 +#$32 +#$33 +#$34 +#$35 +#$36 +#$37 +#$38 +#$39 +#$3A +#$3B +#$3C
  102. +#$3D +#$3E +#$3F +#$00 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40
  103. +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40
  104. +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40;
  105. ReTableXX =
  106. #$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$00 +#$40
  107. +#$01 +#$40 +#$40 +#$02 +#$03 +#$04 +#$05 +#$06 +#$07 +#$08 +#$09 +#$0A
  108. +#$0B +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$0C +#$0D +#$0E +#$0F
  109. +#$10 +#$11 +#$12 +#$13 +#$14 +#$15 +#$16 +#$17 +#$18 +#$19 +#$1A +#$1B
  110. +#$1C +#$1D +#$1E +#$1F +#$20 +#$21 +#$22 +#$23 +#$24 +#$25 +#$40 +#$40
  111. +#$40 +#$40 +#$40 +#$40 +#$26 +#$27 +#$28 +#$29 +#$2A +#$2B +#$2C +#$2D
  112. +#$2E +#$2F +#$30 +#$31 +#$32 +#$33 +#$34 +#$35 +#$36 +#$37 +#$38 +#$39
  113. +#$3A +#$3B +#$3C +#$3D +#$3E +#$3F +#$40 +#$40 +#$40 +#$40 +#$40 +#$40;
  114. {:Decodes triplet encoding with a given character delimiter. It is used for
  115. decoding quoted-printable or URL encoding.}
  116. function DecodeTriplet(const Value: AnsiString; Delimiter: AnsiChar): AnsiString;
  117. {:Decodes a string from quoted printable form. (also decodes triplet sequences
  118. like '=7F')}
  119. function DecodeQuotedPrintable(const Value: AnsiString): AnsiString;
  120. {:Decodes a string of URL encoding. (also decodes triplet sequences like '%7F')}
  121. function DecodeURL(const Value: AnsiString): AnsiString;
  122. {:Performs triplet encoding with a given character delimiter. Used for encoding
  123. quoted-printable or URL encoding.}
  124. function EncodeTriplet(const Value: AnsiString; Delimiter: AnsiChar;
  125. Specials: TSpecials): AnsiString;
  126. {:Encodes a string to triplet quoted printable form. All @link(NonAsciiChar)
  127. are encoded.}
  128. function EncodeQuotedPrintable(const Value: AnsiString): AnsiString;
  129. {:Encodes a string to triplet quoted printable form. All @link(NonAsciiChar) and
  130. @link(SpecialChar) are encoded.}
  131. function EncodeSafeQuotedPrintable(const Value: AnsiString): AnsiString;
  132. {:Encodes a string to URL format. Used for encoding data from a form field in
  133. HTTP, etc. (Encodes all critical characters including characters used as URL
  134. delimiters ('/',':', etc.)}
  135. function EncodeURLElement(const Value: AnsiString): AnsiString;
  136. {:Encodes a string to URL format. Used to encode critical characters in all
  137. URLs.}
  138. function EncodeURL(const Value: AnsiString): AnsiString;
  139. {:Decode 4to3 encoding with given table. If some element is not found in table,
  140. first item from table is used. This is good for buggy coded items by Microsoft
  141. Outlook. This software sometimes using wrong table for UUcode, where is used
  142. ' ' instead '`'.}
  143. function Decode4to3(const Value, Table: AnsiString): AnsiString;
  144. {:Decode 4to3 encoding with given REVERSE table. Using this function with
  145. reverse table is much faster then @link(Decode4to3). This function is used
  146. internally for Base64, UU or XX decoding.}
  147. function Decode4to3Ex(const Value, Table: AnsiString): AnsiString;
  148. {:Encode by system 3to4 (used by Base64, UU coding, etc) by given table.}
  149. function Encode3to4(const Value, Table: AnsiString): AnsiString;
  150. {:Decode string from base64 format.}
  151. function DecodeBase64(const Value: AnsiString): AnsiString;
  152. {:Encodes a string to base64 format.}
  153. function EncodeBase64(const Value: AnsiString): AnsiString;
  154. {:Decode string from modified base64 format. (used in IMAP, for example.)}
  155. function DecodeBase64mod(const Value: AnsiString): AnsiString;
  156. {:Encodes a string to modified base64 format. (used in IMAP, for example.)}
  157. function EncodeBase64mod(const Value: AnsiString): AnsiString;
  158. {:Decodes a string from UUcode format.}
  159. function DecodeUU(const Value: AnsiString): AnsiString;
  160. {:encode UUcode. it encode only datas, you must also add header and footer for
  161. proper encode.}
  162. function EncodeUU(const Value: AnsiString): AnsiString;
  163. {:Decodes a string from XXcode format.}
  164. function DecodeXX(const Value: AnsiString): AnsiString;
  165. {:decode line with Yenc code. This code is sometimes used in newsgroups.}
  166. function DecodeYEnc(const Value: AnsiString): AnsiString;
  167. {:Returns a new CRC32 value after adding a new byte of data.}
  168. function UpdateCrc32(Value: Byte; Crc32: Integer): Integer;
  169. {:return CRC32 from a value string.}
  170. function Crc32(const Value: AnsiString): Integer;
  171. {:Returns a new CRC16 value after adding a new byte of data.}
  172. function UpdateCrc16(Value: Byte; Crc16: Word): Word;
  173. {:return CRC16 from a value string.}
  174. function Crc16(const Value: AnsiString): Word;
  175. {:Returns a binary string with a RSA-MD5 hashing of "Value" string.}
  176. function MD5(const Value: AnsiString): AnsiString;
  177. {:Returns a binary string with HMAC-MD5 hash.}
  178. function HMAC_MD5(Text, Key: AnsiString): AnsiString;
  179. {:Returns a binary string with a RSA-MD5 hashing of string what is constructed
  180. by repeating "value" until length is "Len".}
  181. function MD5LongHash(const Value: AnsiString; Len: integer): AnsiString;
  182. {:Returns a binary string with a SHA-1 hashing of "Value" string.}
  183. function SHA1(const Value: AnsiString): AnsiString;
  184. {:Returns a binary string with HMAC-SHA1 hash.}
  185. function HMAC_SHA1(Text, Key: AnsiString): AnsiString;
  186. {:Returns a binary string with a SHA-1 hashing of string what is constructed
  187. by repeating "value" until length is "Len".}
  188. function SHA1LongHash(const Value: AnsiString; Len: integer): AnsiString;
  189. {:Returns a binary string with a RSA-MD4 hashing of "Value" string.}
  190. function MD4(const Value: AnsiString): AnsiString;
  191. implementation
  192. const
  193. Crc32Tab: array[0..255] of Integer = (
  194. Integer($00000000), Integer($77073096), Integer($EE0E612C), Integer($990951BA),
  195. Integer($076DC419), Integer($706AF48F), Integer($E963A535), Integer($9E6495A3),
  196. Integer($0EDB8832), Integer($79DCB8A4), Integer($E0D5E91E), Integer($97D2D988),
  197. Integer($09B64C2B), Integer($7EB17CBD), Integer($E7B82D07), Integer($90BF1D91),
  198. Integer($1DB71064), Integer($6AB020F2), Integer($F3B97148), Integer($84BE41DE),
  199. Integer($1ADAD47D), Integer($6DDDE4EB), Integer($F4D4B551), Integer($83D385C7),
  200. Integer($136C9856), Integer($646BA8C0), Integer($FD62F97A), Integer($8A65C9EC),
  201. Integer($14015C4F), Integer($63066CD9), Integer($FA0F3D63), Integer($8D080DF5),
  202. Integer($3B6E20C8), Integer($4C69105E), Integer($D56041E4), Integer($A2677172),
  203. Integer($3C03E4D1), Integer($4B04D447), Integer($D20D85FD), Integer($A50AB56B),
  204. Integer($35B5A8FA), Integer($42B2986C), Integer($DBBBC9D6), Integer($ACBCF940),
  205. Integer($32D86CE3), Integer($45DF5C75), Integer($DCD60DCF), Integer($ABD13D59),
  206. Integer($26D930AC), Integer($51DE003A), Integer($C8D75180), Integer($BFD06116),
  207. Integer($21B4F4B5), Integer($56B3C423), Integer($CFBA9599), Integer($B8BDA50F),
  208. Integer($2802B89E), Integer($5F058808), Integer($C60CD9B2), Integer($B10BE924),
  209. Integer($2F6F7C87), Integer($58684C11), Integer($C1611DAB), Integer($B6662D3D),
  210. Integer($76DC4190), Integer($01DB7106), Integer($98D220BC), Integer($EFD5102A),
  211. Integer($71B18589), Integer($06B6B51F), Integer($9FBFE4A5), Integer($E8B8D433),
  212. Integer($7807C9A2), Integer($0F00F934), Integer($9609A88E), Integer($E10E9818),
  213. Integer($7F6A0DBB), Integer($086D3D2D), Integer($91646C97), Integer($E6635C01),
  214. Integer($6B6B51F4), Integer($1C6C6162), Integer($856530D8), Integer($F262004E),
  215. Integer($6C0695ED), Integer($1B01A57B), Integer($8208F4C1), Integer($F50FC457),
  216. Integer($65B0D9C6), Integer($12B7E950), Integer($8BBEB8EA), Integer($FCB9887C),
  217. Integer($62DD1DDF), Integer($15DA2D49), Integer($8CD37CF3), Integer($FBD44C65),
  218. Integer($4DB26158), Integer($3AB551CE), Integer($A3BC0074), Integer($D4BB30E2),
  219. Integer($4ADFA541), Integer($3DD895D7), Integer($A4D1C46D), Integer($D3D6F4FB),
  220. Integer($4369E96A), Integer($346ED9FC), Integer($AD678846), Integer($DA60B8D0),
  221. Integer($44042D73), Integer($33031DE5), Integer($AA0A4C5F), Integer($DD0D7CC9),
  222. Integer($5005713C), Integer($270241AA), Integer($BE0B1010), Integer($C90C2086),
  223. Integer($5768B525), Integer($206F85B3), Integer($B966D409), Integer($CE61E49F),
  224. Integer($5EDEF90E), Integer($29D9C998), Integer($B0D09822), Integer($C7D7A8B4),
  225. Integer($59B33D17), Integer($2EB40D81), Integer($B7BD5C3B), Integer($C0BA6CAD),
  226. Integer($EDB88320), Integer($9ABFB3B6), Integer($03B6E20C), Integer($74B1D29A),
  227. Integer($EAD54739), Integer($9DD277AF), Integer($04DB2615), Integer($73DC1683),
  228. Integer($E3630B12), Integer($94643B84), Integer($0D6D6A3E), Integer($7A6A5AA8),
  229. Integer($E40ECF0B), Integer($9309FF9D), Integer($0A00AE27), Integer($7D079EB1),
  230. Integer($F00F9344), Integer($8708A3D2), Integer($1E01F268), Integer($6906C2FE),
  231. Integer($F762575D), Integer($806567CB), Integer($196C3671), Integer($6E6B06E7),
  232. Integer($FED41B76), Integer($89D32BE0), Integer($10DA7A5A), Integer($67DD4ACC),
  233. Integer($F9B9DF6F), Integer($8EBEEFF9), Integer($17B7BE43), Integer($60B08ED5),
  234. Integer($D6D6A3E8), Integer($A1D1937E), Integer($38D8C2C4), Integer($4FDFF252),
  235. Integer($D1BB67F1), Integer($A6BC5767), Integer($3FB506DD), Integer($48B2364B),
  236. Integer($D80D2BDA), Integer($AF0A1B4C), Integer($36034AF6), Integer($41047A60),
  237. Integer($DF60EFC3), Integer($A867DF55), Integer($316E8EEF), Integer($4669BE79),
  238. Integer($CB61B38C), Integer($BC66831A), Integer($256FD2A0), Integer($5268E236),
  239. Integer($CC0C7795), Integer($BB0B4703), Integer($220216B9), Integer($5505262F),
  240. Integer($C5BA3BBE), Integer($B2BD0B28), Integer($2BB45A92), Integer($5CB36A04),
  241. Integer($C2D7FFA7), Integer($B5D0CF31), Integer($2CD99E8B), Integer($5BDEAE1D),
  242. Integer($9B64C2B0), Integer($EC63F226), Integer($756AA39C), Integer($026D930A),
  243. Integer($9C0906A9), Integer($EB0E363F), Integer($72076785), Integer($05005713),
  244. Integer($95BF4A82), Integer($E2B87A14), Integer($7BB12BAE), Integer($0CB61B38),
  245. Integer($92D28E9B), Integer($E5D5BE0D), Integer($7CDCEFB7), Integer($0BDBDF21),
  246. Integer($86D3D2D4), Integer($F1D4E242), Integer($68DDB3F8), Integer($1FDA836E),
  247. Integer($81BE16CD), Integer($F6B9265B), Integer($6FB077E1), Integer($18B74777),
  248. Integer($88085AE6), Integer($FF0F6A70), Integer($66063BCA), Integer($11010B5C),
  249. Integer($8F659EFF), Integer($F862AE69), Integer($616BFFD3), Integer($166CCF45),
  250. Integer($A00AE278), Integer($D70DD2EE), Integer($4E048354), Integer($3903B3C2),
  251. Integer($A7672661), Integer($D06016F7), Integer($4969474D), Integer($3E6E77DB),
  252. Integer($AED16A4A), Integer($D9D65ADC), Integer($40DF0B66), Integer($37D83BF0),
  253. Integer($A9BCAE53), Integer($DEBB9EC5), Integer($47B2CF7F), Integer($30B5FFE9),
  254. Integer($BDBDF21C), Integer($CABAC28A), Integer($53B39330), Integer($24B4A3A6),
  255. Integer($BAD03605), Integer($CDD70693), Integer($54DE5729), Integer($23D967BF),
  256. Integer($B3667A2E), Integer($C4614AB8), Integer($5D681B02), Integer($2A6F2B94),
  257. Integer($B40BBE37), Integer($C30C8EA1), Integer($5A05DF1B), Integer($2D02EF8D)
  258. );
  259. Crc16Tab: array[0..255] of Word = (
  260. $0000, $1189, $2312, $329B, $4624, $57AD, $6536, $74BF,
  261. $8C48, $9DC1, $AF5A, $BED3, $CA6C, $DBE5, $E97E, $F8F7,
  262. $1081, $0108, $3393, $221A, $56A5, $472C, $75B7, $643E,
  263. $9CC9, $8D40, $BFDB, $AE52, $DAED, $CB64, $F9FF, $E876,
  264. $2102, $308B, $0210, $1399, $6726, $76AF, $4434, $55BD,
  265. $AD4A, $BCC3, $8E58, $9FD1, $EB6E, $FAE7, $C87C, $D9F5,
  266. $3183, $200A, $1291, $0318, $77A7, $662E, $54B5, $453C,
  267. $BDCB, $AC42, $9ED9, $8F50, $FBEF, $EA66, $D8FD, $C974,
  268. $4204, $538D, $6116, $709F, $0420, $15A9, $2732, $36BB,
  269. $CE4C, $DFC5, $ED5E, $FCD7, $8868, $99E1, $AB7A, $BAF3,
  270. $5285, $430C, $7197, $601E, $14A1, $0528, $37B3, $263A,
  271. $DECD, $CF44, $FDDF, $EC56, $98E9, $8960, $BBFB, $AA72,
  272. $6306, $728F, $4014, $519D, $2522, $34AB, $0630, $17B9,
  273. $EF4E, $FEC7, $CC5C, $DDD5, $A96A, $B8E3, $8A78, $9BF1,
  274. $7387, $620E, $5095, $411C, $35A3, $242A, $16B1, $0738,
  275. $FFCF, $EE46, $DCDD, $CD54, $B9EB, $A862, $9AF9, $8B70,
  276. $8408, $9581, $A71A, $B693, $C22C, $D3A5, $E13E, $F0B7,
  277. $0840, $19C9, $2B52, $3ADB, $4E64, $5FED, $6D76, $7CFF,
  278. $9489, $8500, $B79B, $A612, $D2AD, $C324, $F1BF, $E036,
  279. $18C1, $0948, $3BD3, $2A5A, $5EE5, $4F6C, $7DF7, $6C7E,
  280. $A50A, $B483, $8618, $9791, $E32E, $F2A7, $C03C, $D1B5,
  281. $2942, $38CB, $0A50, $1BD9, $6F66, $7EEF, $4C74, $5DFD,
  282. $B58B, $A402, $9699, $8710, $F3AF, $E226, $D0BD, $C134,
  283. $39C3, $284A, $1AD1, $0B58, $7FE7, $6E6E, $5CF5, $4D7C,
  284. $C60C, $D785, $E51E, $F497, $8028, $91A1, $A33A, $B2B3,
  285. $4A44, $5BCD, $6956, $78DF, $0C60, $1DE9, $2F72, $3EFB,
  286. $D68D, $C704, $F59F, $E416, $90A9, $8120, $B3BB, $A232,
  287. $5AC5, $4B4C, $79D7, $685E, $1CE1, $0D68, $3FF3, $2E7A,
  288. $E70E, $F687, $C41C, $D595, $A12A, $B0A3, $8238, $93B1,
  289. $6B46, $7ACF, $4854, $59DD, $2D62, $3CEB, $0E70, $1FF9,
  290. $F78F, $E606, $D49D, $C514, $B1AB, $A022, $92B9, $8330,
  291. $7BC7, $6A4E, $58D5, $495C, $3DE3, $2C6A, $1EF1, $0F78
  292. );
  293. procedure ArrByteToLong(var ArByte: Array of byte; var ArLong: Array of Integer);
  294. {$IFDEF SYNACODE_NATIVE}
  295. var
  296. n: integer;
  297. {$ENDIF}
  298. begin
  299. if (High(ArByte) + 1) > ((High(ArLong) + 1) * 4) then
  300. Exit;
  301. {$IFDEF SYNACODE_NATIVE}
  302. for n := 0 to ((high(ArByte) + 1) div 4) - 1 do
  303. ArLong[n] := ArByte[n * 4 + 0]
  304. + (ArByte[n * 4 + 1] shl 8)
  305. + (ArByte[n * 4 + 2] shl 16)
  306. + (ArByte[n * 4 + 3] shl 24);
  307. {$ELSE}
  308. Move(ArByte[0], ArLong[0], High(ArByte) + 1);
  309. {$ENDIF}
  310. end;
  311. procedure ArrLongToByte(var ArLong: Array of Integer; var ArByte: Array of byte);
  312. {$IFDEF SYNACODE_NATIVE}
  313. var
  314. n: integer;
  315. {$ENDIF}
  316. begin
  317. if (High(ArByte) + 1) < ((High(ArLong) + 1) * 4) then
  318. Exit;
  319. {$IFDEF SYNACODE_NATIVE}
  320. for n := 0 to high(ArLong) do
  321. begin
  322. ArByte[n * 4 + 0] := ArLong[n] and $000000FF;
  323. ArByte[n * 4 + 1] := (ArLong[n] shr 8) and $000000FF;
  324. ArByte[n * 4 + 2] := (ArLong[n] shr 16) and $000000FF;
  325. ArByte[n * 4 + 3] := (ArLong[n] shr 24) and $000000FF;
  326. end;
  327. {$ELSE}
  328. Move(ArLong[0], ArByte[0], High(ArByte) + 1);
  329. {$ENDIF}
  330. end;
  331. type
  332. TMDCtx = record
  333. State: array[0..3] of Integer;
  334. Count: array[0..1] of Integer;
  335. BufAnsiChar: array[0..63] of Byte;
  336. BufLong: array[0..15] of Integer;
  337. end;
  338. TSHA1Ctx= record
  339. Hi, Lo: integer;
  340. Buffer: array[0..63] of byte;
  341. Index: integer;
  342. Hash: array[0..4] of Integer;
  343. HashByte: array[0..19] of byte;
  344. end;
  345. TMDTransform = procedure(var Buf: array of LongInt; const Data: array of LongInt);
  346. {==============================================================================}
  347. function DecodeTriplet(const Value: AnsiString; Delimiter: AnsiChar): AnsiString;
  348. var
  349. x, l, lv: Integer;
  350. c: AnsiChar;
  351. b: Byte;
  352. bad: Boolean;
  353. begin
  354. lv := Length(Value);
  355. SetLength(Result, lv);
  356. x := 1;
  357. l := 1;
  358. while x <= lv do
  359. begin
  360. c := Value[x];
  361. Inc(x);
  362. if c <> Delimiter then
  363. begin
  364. Result[l] := c;
  365. Inc(l);
  366. end
  367. else
  368. if x < lv then
  369. begin
  370. Case Value[x] Of
  371. #13:
  372. if (Value[x + 1] = #10) then
  373. Inc(x, 2)
  374. else
  375. Inc(x);
  376. #10:
  377. if (Value[x + 1] = #13) then
  378. Inc(x, 2)
  379. else
  380. Inc(x);
  381. else
  382. begin
  383. bad := False;
  384. Case Value[x] Of
  385. '0'..'9': b := (Byte(Value[x]) - 48) Shl 4;
  386. 'a'..'f', 'A'..'F': b := ((Byte(Value[x]) And 7) + 9) shl 4;
  387. else
  388. begin
  389. b := 0;
  390. bad := True;
  391. end;
  392. end;
  393. Case Value[x + 1] Of
  394. '0'..'9': b := b Or (Byte(Value[x + 1]) - 48);
  395. 'a'..'f', 'A'..'F': b := b Or ((Byte(Value[x + 1]) And 7) + 9);
  396. else
  397. bad := True;
  398. end;
  399. if bad then
  400. begin
  401. Result[l] := c;
  402. Inc(l);
  403. end
  404. else
  405. begin
  406. Inc(x, 2);
  407. Result[l] := AnsiChar(b);
  408. Inc(l);
  409. end;
  410. end;
  411. end;
  412. end
  413. else
  414. break;
  415. end;
  416. Dec(l);
  417. SetLength(Result, l);
  418. end;
  419. {==============================================================================}
  420. function DecodeQuotedPrintable(const Value: AnsiString): AnsiString;
  421. begin
  422. Result := DecodeTriplet(Value, '=');
  423. end;
  424. {==============================================================================}
  425. function DecodeURL(const Value: AnsiString): AnsiString;
  426. begin
  427. Result := DecodeTriplet(Value, '%');
  428. end;
  429. {==============================================================================}
  430. function EncodeTriplet(const Value: AnsiString; Delimiter: AnsiChar;
  431. Specials: TSpecials): AnsiString;
  432. var
  433. n, l: Integer;
  434. s: AnsiString;
  435. c: AnsiChar;
  436. begin
  437. SetLength(Result, Length(Value) * 3);
  438. l := 1;
  439. for n := 1 to Length(Value) do
  440. begin
  441. c := Value[n];
  442. if c in Specials then
  443. begin
  444. Result[l] := Delimiter;
  445. Inc(l);
  446. s := IntToHex(Ord(c), 2);
  447. Result[l] := s[1];
  448. Inc(l);
  449. Result[l] := s[2];
  450. Inc(l);
  451. end
  452. else
  453. begin
  454. Result[l] := c;
  455. Inc(l);
  456. end;
  457. end;
  458. Dec(l);
  459. SetLength(Result, l);
  460. end;
  461. {==============================================================================}
  462. function EncodeQuotedPrintable(const Value: AnsiString): AnsiString;
  463. begin
  464. Result := EncodeTriplet(Value, '=', ['='] + NonAsciiChar);
  465. end;
  466. {==============================================================================}
  467. function EncodeSafeQuotedPrintable(const Value: AnsiString): AnsiString;
  468. begin
  469. Result := EncodeTriplet(Value, '=', SpecialChar + NonAsciiChar);
  470. end;
  471. {==============================================================================}
  472. function EncodeURLElement(const Value: AnsiString): AnsiString;
  473. begin
  474. Result := EncodeTriplet(Value, '%', URLSpecialChar + URLFullSpecialChar);
  475. end;
  476. {==============================================================================}
  477. function EncodeURL(const Value: AnsiString): AnsiString;
  478. begin
  479. Result := EncodeTriplet(Value, '%', URLSpecialChar);
  480. end;
  481. {==============================================================================}
  482. function Decode4to3(const Value, Table: AnsiString): AnsiString;
  483. var
  484. x, y, n, l: Integer;
  485. d: array[0..3] of Byte;
  486. begin
  487. SetLength(Result, Length(Value));
  488. x := 1;
  489. l := 1;
  490. while x <= Length(Value) do
  491. begin
  492. for n := 0 to 3 do
  493. begin
  494. if x > Length(Value) then
  495. d[n] := 64
  496. else
  497. begin
  498. y := Pos(Value[x], Table);
  499. if y < 1 then
  500. y := 1;
  501. d[n] := y - 1;
  502. end;
  503. Inc(x);
  504. end;
  505. Result[l] := AnsiChar((D[0] and $3F) shl 2 + (D[1] and $30) shr 4);
  506. Inc(l);
  507. if d[2] <> 64 then
  508. begin
  509. Result[l] := AnsiChar((D[1] and $0F) shl 4 + (D[2] and $3C) shr 2);
  510. Inc(l);
  511. if d[3] <> 64 then
  512. begin
  513. Result[l] := AnsiChar((D[2] and $03) shl 6 + (D[3] and $3F));
  514. Inc(l);
  515. end;
  516. end;
  517. end;
  518. Dec(l);
  519. SetLength(Result, l);
  520. end;
  521. {==============================================================================}
  522. function Decode4to3Ex(const Value, Table: AnsiString): AnsiString;
  523. var
  524. x, y, lv: Integer;
  525. d: integer;
  526. dl: integer;
  527. c: byte;
  528. p: integer;
  529. begin
  530. lv := Length(Value);
  531. SetLength(Result, lv);
  532. x := 1;
  533. dl := 4;
  534. d := 0;
  535. p := 1;
  536. while x <= lv do
  537. begin
  538. y := Ord(Value[x]);
  539. if y in [33..127] then
  540. c := Ord(Table[y - 32])
  541. else
  542. c := 64;
  543. Inc(x);
  544. if c > 63 then
  545. continue;
  546. d := (d shl 6) or c;
  547. dec(dl);
  548. if dl <> 0 then
  549. continue;
  550. Result[p] := AnsiChar((d shr 16) and $ff);
  551. inc(p);
  552. Result[p] := AnsiChar((d shr 8) and $ff);
  553. inc(p);
  554. Result[p] := AnsiChar(d and $ff);
  555. inc(p);
  556. d := 0;
  557. dl := 4;
  558. end;
  559. case dl of
  560. 1:
  561. begin
  562. d := d shr 2;
  563. Result[p] := AnsiChar((d shr 8) and $ff);
  564. inc(p);
  565. Result[p] := AnsiChar(d and $ff);
  566. inc(p);
  567. end;
  568. 2:
  569. begin
  570. d := d shr 4;
  571. Result[p] := AnsiChar(d and $ff);
  572. inc(p);
  573. end;
  574. end;
  575. SetLength(Result, p - 1);
  576. end;
  577. {==============================================================================}
  578. function Encode3to4(const Value, Table: AnsiString): AnsiString;
  579. var
  580. c: Byte;
  581. n, l: Integer;
  582. Count: Integer;
  583. DOut: array[0..3] of Byte;
  584. begin
  585. setlength(Result, ((Length(Value) + 2) div 3) * 4);
  586. l := 1;
  587. Count := 1;
  588. while Count <= Length(Value) do
  589. begin
  590. c := Ord(Value[Count]);
  591. Inc(Count);
  592. DOut[0] := (c and $FC) shr 2;
  593. DOut[1] := (c and $03) shl 4;
  594. if Count <= Length(Value) then
  595. begin
  596. c := Ord(Value[Count]);
  597. Inc(Count);
  598. DOut[1] := DOut[1] + (c and $F0) shr 4;
  599. DOut[2] := (c and $0F) shl 2;
  600. if Count <= Length(Value) then
  601. begin
  602. c := Ord(Value[Count]);
  603. Inc(Count);
  604. DOut[2] := DOut[2] + (c and $C0) shr 6;
  605. DOut[3] := (c and $3F);
  606. end
  607. else
  608. begin
  609. DOut[3] := $40;
  610. end;
  611. end
  612. else
  613. begin
  614. DOut[2] := $40;
  615. DOut[3] := $40;
  616. end;
  617. for n := 0 to 3 do
  618. begin
  619. if (DOut[n] + 1) <= Length(Table) then
  620. begin
  621. Result[l] := Table[DOut[n] + 1];
  622. Inc(l);
  623. end;
  624. end;
  625. end;
  626. SetLength(Result, l - 1);
  627. end;
  628. {==============================================================================}
  629. function DecodeBase64(const Value: AnsiString): AnsiString;
  630. begin
  631. Result := Decode4to3Ex(Value, ReTableBase64);
  632. end;
  633. {==============================================================================}
  634. function EncodeBase64(const Value: AnsiString): AnsiString;
  635. begin
  636. Result := Encode3to4(Value, TableBase64);
  637. end;
  638. {==============================================================================}
  639. function DecodeBase64mod(const Value: AnsiString): AnsiString;
  640. begin
  641. Result := Decode4to3(Value, TableBase64mod);
  642. end;
  643. {==============================================================================}
  644. function EncodeBase64mod(const Value: AnsiString): AnsiString;
  645. begin
  646. Result := Encode3to4(Value, TableBase64mod);
  647. end;
  648. {==============================================================================}
  649. function DecodeUU(const Value: AnsiString): AnsiString;
  650. var
  651. s: AnsiString;
  652. uut: AnsiString;
  653. x: Integer;
  654. begin
  655. Result := '';
  656. uut := TableUU;
  657. s := trim(UpperCase(Value));
  658. if s = '' then Exit;
  659. if Pos('BEGIN', s) = 1 then
  660. Exit;
  661. if Pos('END', s) = 1 then
  662. Exit;
  663. if Pos('TABLE', s) = 1 then
  664. Exit; //ignore Table yet (set custom UUT)
  665. //begin decoding
  666. x := Pos(Value[1], uut) - 1;
  667. case (x mod 3) of
  668. 0: x :=(x div 3)* 4;
  669. 1: x :=((x div 3) * 4) + 2;
  670. 2: x :=((x div 3) * 4) + 3;
  671. end;
  672. //x - lenght UU line
  673. s := Copy(Value, 2, x);
  674. if s = '' then
  675. Exit;
  676. s := s + StringOfChar(' ', x - length(s));
  677. Result := Decode4to3(s, uut);
  678. end;
  679. {==============================================================================}
  680. function EncodeUU(const Value: AnsiString): AnsiString;
  681. begin
  682. Result := '';
  683. if Length(Value) < Length(TableUU) then
  684. Result := TableUU[Length(Value) + 1] + Encode3to4(Value, TableUU);
  685. end;
  686. {==============================================================================}
  687. function DecodeXX(const Value: AnsiString): AnsiString;
  688. var
  689. s: AnsiString;
  690. x: Integer;
  691. begin
  692. Result := '';
  693. s := trim(UpperCase(Value));
  694. if s = '' then
  695. Exit;
  696. if Pos('BEGIN', s) = 1 then
  697. Exit;
  698. if Pos('END', s) = 1 then
  699. Exit;
  700. //begin decoding
  701. x := Pos(Value[1], TableXX) - 1;
  702. case (x mod 3) of
  703. 0: x :=(x div 3)* 4;
  704. 1: x :=((x div 3) * 4) + 2;
  705. 2: x :=((x div 3) * 4) + 3;
  706. end;
  707. //x - lenght XX line
  708. s := Copy(Value, 2, x);
  709. if s = '' then
  710. Exit;
  711. s := s + StringOfChar(' ', x - length(s));
  712. Result := Decode4to3(s, TableXX);
  713. end;
  714. {==============================================================================}
  715. function DecodeYEnc(const Value: AnsiString): AnsiString;
  716. var
  717. C : Byte;
  718. i: integer;
  719. begin
  720. Result := '';
  721. i := 1;
  722. while i <= Length(Value) do
  723. begin
  724. c := Ord(Value[i]);
  725. Inc(i);
  726. if c = Ord('=') then
  727. begin
  728. c := Ord(Value[i]);
  729. Inc(i);
  730. Dec(c, 64);
  731. end;
  732. Dec(C, 42);
  733. Result := Result + AnsiChar(C);
  734. end;
  735. end;
  736. {==============================================================================}
  737. function UpdateCrc32(Value: Byte; Crc32: Integer): Integer;
  738. begin
  739. Result := (Crc32 shr 8)
  740. xor crc32tab[Byte(Value xor (Crc32 and Integer($000000FF)))];
  741. end;
  742. {==============================================================================}
  743. function Crc32(const Value: AnsiString): Integer;
  744. var
  745. n: Integer;
  746. begin
  747. Result := Integer($FFFFFFFF);
  748. for n := 1 to Length(Value) do
  749. Result := UpdateCrc32(Ord(Value[n]), Result);
  750. Result := not Result;
  751. end;
  752. {==============================================================================}
  753. function UpdateCrc16(Value: Byte; Crc16: Word): Word;
  754. begin
  755. Result := ((Crc16 shr 8) and $00FF) xor
  756. crc16tab[Byte(Crc16 xor (Word(Value)) and $00FF)];
  757. end;
  758. {==============================================================================}
  759. function Crc16(const Value: AnsiString): Word;
  760. var
  761. n: Integer;
  762. begin
  763. Result := $FFFF;
  764. for n := 1 to Length(Value) do
  765. Result := UpdateCrc16(Ord(Value[n]), Result);
  766. end;
  767. {==============================================================================}
  768. procedure MDInit(var MDContext: TMDCtx);
  769. var
  770. n: integer;
  771. begin
  772. MDContext.Count[0] := 0;
  773. MDContext.Count[1] := 0;
  774. for n := 0 to high(MDContext.BufAnsiChar) do
  775. MDContext.BufAnsiChar[n] := 0;
  776. for n := 0 to high(MDContext.BufLong) do
  777. MDContext.BufLong[n] := 0;
  778. MDContext.State[0] := Integer($67452301);
  779. MDContext.State[1] := Integer($EFCDAB89);
  780. MDContext.State[2] := Integer($98BADCFE);
  781. MDContext.State[3] := Integer($10325476);
  782. end;
  783. procedure MD5Transform(var Buf: array of LongInt; const Data: array of LongInt);
  784. var
  785. A, B, C, D: LongInt;
  786. procedure Round1(var W: LongInt; X, Y, Z, Data: LongInt; S: Byte);
  787. begin
  788. Inc(W, (Z xor (X and (Y xor Z))) + Data);
  789. W := (W shl S) or (W shr (32 - S));
  790. Inc(W, X);
  791. end;
  792. procedure Round2(var W: LongInt; X, Y, Z, Data: LongInt; S: Byte);
  793. begin
  794. Inc(W, (Y xor (Z and (X xor Y))) + Data);
  795. W := (W shl S) or (W shr (32 - S));
  796. Inc(W, X);
  797. end;
  798. procedure Round3(var W: LongInt; X, Y, Z, Data: LongInt; S: Byte);
  799. begin
  800. Inc(W, (X xor Y xor Z) + Data);
  801. W := (W shl S) or (W shr (32 - S));
  802. Inc(W, X);
  803. end;
  804. procedure Round4(var W: LongInt; X, Y, Z, Data: LongInt; S: Byte);
  805. begin
  806. Inc(W, (Y xor (X or not Z)) + Data);
  807. W := (W shl S) or (W shr (32 - S));
  808. Inc(W, X);
  809. end;
  810. begin
  811. A := Buf[0];
  812. B := Buf[1];
  813. C := Buf[2];
  814. D := Buf[3];
  815. Round1(A, B, C, D, Data[0] + Longint($D76AA478), 7);
  816. Round1(D, A, B, C, Data[1] + Longint($E8C7B756), 12);
  817. Round1(C, D, A, B, Data[2] + Longint($242070DB), 17);
  818. Round1(B, C, D, A, Data[3] + Longint($C1BDCEEE), 22);
  819. Round1(A, B, C, D, Data[4] + Longint($F57C0FAF), 7);
  820. Round1(D, A, B, C, Data[5] + Longint($4787C62A), 12);
  821. Round1(C, D, A, B, Data[6] + Longint($A8304613), 17);
  822. Round1(B, C, D, A, Data[7] + Longint($FD469501), 22);
  823. Round1(A, B, C, D, Data[8] + Longint($698098D8), 7);
  824. Round1(D, A, B, C, Data[9] + Longint($8B44F7AF), 12);
  825. Round1(C, D, A, B, Data[10] + Longint($FFFF5BB1), 17);
  826. Round1(B, C, D, A, Data[11] + Longint($895CD7BE), 22);
  827. Round1(A, B, C, D, Data[12] + Longint($6B901122), 7);
  828. Round1(D, A, B, C, Data[13] + Longint($FD987193), 12);
  829. Round1(C, D, A, B, Data[14] + Longint($A679438E), 17);
  830. Round1(B, C, D, A, Data[15] + Longint($49B40821), 22);
  831. Round2(A, B, C, D, Data[1] + Longint($F61E2562), 5);
  832. Round2(D, A, B, C, Data[6] + Longint($C040B340), 9);
  833. Round2(C, D, A, B, Data[11] + Longint($265E5A51), 14);
  834. Round2(B, C, D, A, Data[0] + Longint($E9B6C7AA), 20);
  835. Round2(A, B, C, D, Data[5] + Longint($D62F105D), 5);
  836. Round2(D, A, B, C, Data[10] + Longint($02441453), 9);
  837. Round2(C, D, A, B, Data[15] + Longint($D8A1E681), 14);
  838. Round2(B, C, D, A, Data[4] + Longint($E7D3FBC8), 20);
  839. Round2(A, B, C, D, Data[9] + Longint($21E1CDE6), 5);
  840. Round2(D, A, B, C, Data[14] + Longint($C33707D6), 9);
  841. Round2(C, D, A, B, Data[3] + Longint($F4D50D87), 14);
  842. Round2(B, C, D, A, Data[8] + Longint($455A14ED), 20);
  843. Round2(A, B, C, D, Data[13] + Longint($A9E3E905), 5);
  844. Round2(D, A, B, C, Data[2] + Longint($FCEFA3F8), 9);
  845. Round2(C, D, A, B, Data[7] + Longint($676F02D9), 14);
  846. Round2(B, C, D, A, Data[12] + Longint($8D2A4C8A), 20);
  847. Round3(A, B, C, D, Data[5] + Longint($FFFA3942), 4);
  848. Round3(D, A, B, C, Data[8] + Longint($8771F681), 11);
  849. Round3(C, D, A, B, Data[11] + Longint($6D9D6122), 16);
  850. Round3(B, C, D, A, Data[14] + Longint($FDE5380C), 23);
  851. Round3(A, B, C, D, Data[1] + Longint($A4BEEA44), 4);
  852. Round3(D, A, B, C, Data[4] + Longint($4BDECFA9), 11);
  853. Round3(C, D, A, B, Data[7] + Longint($F6BB4B60), 16);
  854. Round3(B, C, D, A, Data[10] + Longint($BEBFBC70), 23);
  855. Round3(A, B, C, D, Data[13] + Longint($289B7EC6), 4);
  856. Round3(D, A, B, C, Data[0] + Longint($EAA127FA), 11);
  857. Round3(C, D, A, B, Data[3] + Longint($D4EF3085), 16);
  858. Round3(B, C, D, A, Data[6] + Longint($04881D05), 23);
  859. Round3(A, B, C, D, Data[9] + Longint($D9D4D039), 4);
  860. Round3(D, A, B, C, Data[12] + Longint($E6DB99E5), 11);
  861. Round3(C, D, A, B, Data[15] + Longint($1FA27CF8), 16);
  862. Round3(B, C, D, A, Data[2] + Longint($C4AC5665), 23);
  863. Round4(A, B, C, D, Data[0] + Longint($F4292244), 6);
  864. Round4(D, A, B, C, Data[7] + Longint($432AFF97), 10);
  865. Round4(C, D, A, B, Data[14] + Longint($AB9423A7), 15);
  866. Round4(B, C, D, A, Data[5] + Longint($FC93A039), 21);
  867. Round4(A, B, C, D, Data[12] + Longint($655B59C3), 6);
  868. Round4(D, A, B, C, Data[3] + Longint($8F0CCC92), 10);
  869. Round4(C, D, A, B, Data[10] + Longint($FFEFF47D), 15);
  870. Round4(B, C, D, A, Data[1] + Longint($85845DD1), 21);
  871. Round4(A, B, C, D, Data[8] + Longint($6FA87E4F), 6);
  872. Round4(D, A, B, C, Data[15] + Longint($FE2CE6E0), 10);
  873. Round4(C, D, A, B, Data[6] + Longint($A3014314), 15);
  874. Round4(B, C, D, A, Data[13] + Longint($4E0811A1), 21);
  875. Round4(A, B, C, D, Data[4] + Longint($F7537E82), 6);
  876. Round4(D, A, B, C, Data[11] + Longint($BD3AF235), 10);
  877. Round4(C, D, A, B, Data[2] + Longint($2AD7D2BB), 15);
  878. Round4(B, C, D, A, Data[9] + Longint($EB86D391), 21);
  879. Inc(Buf[0], A);
  880. Inc(Buf[1], B);
  881. Inc(Buf[2], C);
  882. Inc(Buf[3], D);
  883. end;
  884. //fixed by James McAdams
  885. procedure MDUpdate(var MDContext: TMDCtx; const Data: AnsiString; transform: TMDTransform);
  886. var
  887. Index, partLen, InputLen, I: integer;
  888. {$IFDEF SYNACODE_NATIVE}
  889. n: integer;
  890. {$ENDIF}
  891. begin
  892. InputLen := Length(Data);
  893. with MDContext do
  894. begin
  895. Index := (Count[0] shr 3) and $3F;
  896. Inc(Count[0], InputLen shl 3);
  897. if Count[0] < (InputLen shl 3) then
  898. Inc(Count[1]);
  899. Inc(Count[1], InputLen shr 29);
  900. partLen := 64 - Index;
  901. if InputLen >= partLen then
  902. begin
  903. ArrLongToByte(BufLong, BufAnsiChar);
  904. {$IFDEF SYNACODE_NATIVE}
  905. for n := 1 to partLen do
  906. BufAnsiChar[index - 1 + n] := Ord(Data[n]);
  907. {$ELSE}
  908. Move(Data[1], BufAnsiChar[Index], partLen);
  909. {$ENDIF}
  910. ArrByteToLong(BufAnsiChar, BufLong);
  911. Transform(State, Buflong);
  912. I := partLen;
  913. while I + 63 < InputLen do
  914. begin
  915. ArrLongToByte(BufLong, BufAnsiChar);
  916. {$IFDEF SYNACODE_NATIVE}
  917. for n := 1 to 64 do
  918. BufAnsiChar[n - 1] := Ord(Data[i + n]);
  919. {$ELSE}
  920. Move(Data[I+1], BufAnsiChar, 64);
  921. {$ENDIF}
  922. ArrByteToLong(BufAnsiChar, BufLong);
  923. Transform(State, Buflong);
  924. inc(I, 64);
  925. end;
  926. Index := 0;
  927. end
  928. else
  929. I := 0;
  930. ArrLongToByte(BufLong, BufAnsiChar);
  931. {$IFDEF SYNACODE_NATIVE}
  932. for n := 1 to InputLen-I do
  933. BufAnsiChar[Index + n - 1] := Ord(Data[i + n]);
  934. {$ELSE}
  935. Move(Data[I+1], BufAnsiChar[Index], InputLen-I);
  936. {$ENDIF}
  937. ArrByteToLong(BufAnsiChar, BufLong);
  938. end
  939. end;
  940. function MDFinal(var MDContext: TMDCtx; transform: TMDTransform): AnsiString;
  941. var
  942. Cnt: Word;
  943. P: Byte;
  944. digest: array[0..15] of Byte;
  945. i: Integer;
  946. n: integer;
  947. begin
  948. for I := 0 to 15 do
  949. Digest[I] := I + 1;
  950. with MDContext do
  951. begin
  952. Cnt := (Count[0] shr 3) and $3F;
  953. P := Cnt;
  954. BufAnsiChar[P] := $80;
  955. Inc(P);
  956. Cnt := 64 - 1 - Cnt;
  957. if Cnt < 8 then
  958. begin
  959. for n := 0 to cnt - 1 do
  960. BufAnsiChar[P + n] := 0;
  961. ArrByteToLong(BufAnsiChar, BufLong);
  962. // FillChar(BufAnsiChar[P], Cnt, #0);
  963. Transform(State, BufLong);
  964. ArrLongToByte(BufLong, BufAnsiChar);
  965. for n := 0 to 55 do
  966. BufAnsiChar[n] := 0;
  967. ArrByteToLong(BufAnsiChar, BufLong);
  968. // FillChar(BufAnsiChar, 56, #0);
  969. end
  970. else
  971. begin
  972. for n := 0 to Cnt - 8 - 1 do
  973. BufAnsiChar[p + n] := 0;
  974. ArrByteToLong(BufAnsiChar, BufLong);
  975. // FillChar(BufAnsiChar[P], Cnt - 8, #0);
  976. end;
  977. BufLong[14] := Count[0];
  978. BufLong[15] := Count[1];
  979. Transform(State, BufLong);
  980. ArrLongToByte(State, Digest);
  981. // Move(State, Digest, 16);
  982. Result := '';
  983. for i := 0 to 15 do
  984. Result := Result + AnsiChar(digest[i]);
  985. end;
  986. // FillChar(MD5Context, SizeOf(TMD5Ctx), #0)
  987. end;
  988. {==============================================================================}
  989. function MD5(const Value: AnsiString): AnsiString;
  990. var
  991. MDContext: TMDCtx;
  992. begin
  993. MDInit(MDContext);
  994. MDUpdate(MDContext, Value, @MD5Transform);
  995. Result := MDFinal(MDContext, @MD5Transform);
  996. end;
  997. {==============================================================================}
  998. function HMAC_MD5(Text, Key: AnsiString): AnsiString;
  999. var
  1000. ipad, opad, s: AnsiString;
  1001. n: Integer;
  1002. MDContext: TMDCtx;
  1003. begin
  1004. if Length(Key) > 64 then
  1005. Key := md5(Key);
  1006. ipad := StringOfChar(#$36, 64);
  1007. opad := StringOfChar(#$5C, 64);
  1008. for n := 1 to Length(Key) do
  1009. begin
  1010. ipad[n] := AnsiChar(Byte(ipad[n]) xor Byte(Key[n]));
  1011. opad[n] := AnsiChar(Byte(opad[n]) xor Byte(Key[n]));
  1012. end;
  1013. MDInit(MDContext);
  1014. MDUpdate(MDContext, ipad, @MD5Transform);
  1015. MDUpdate(MDContext, Text, @MD5Transform);
  1016. s := MDFinal(MDContext, @MD5Transform);
  1017. MDInit(MDContext);
  1018. MDUpdate(MDContext, opad, @MD5Transform);
  1019. MDUpdate(MDContext, s, @MD5Transform);
  1020. Result := MDFinal(MDContext, @MD5Transform);
  1021. end;
  1022. {==============================================================================}
  1023. function MD5LongHash(const Value: AnsiString; Len: integer): AnsiString;
  1024. var
  1025. cnt, rest: integer;
  1026. l: integer;
  1027. n: integer;
  1028. MDContext: TMDCtx;
  1029. begin
  1030. l := length(Value);
  1031. cnt := Len div l;
  1032. rest := Len mod l;
  1033. MDInit(MDContext);
  1034. for n := 1 to cnt do
  1035. MDUpdate(MDContext, Value, @MD5Transform);
  1036. if rest > 0 then
  1037. MDUpdate(MDContext, Copy(Value, 1, rest), @MD5Transform);
  1038. Result := MDFinal(MDContext, @MD5Transform);
  1039. end;
  1040. {==============================================================================}
  1041. // SHA1 is based on sources by Dave Barton ([email protected])
  1042. procedure SHA1init( var SHA1Context: TSHA1Ctx );
  1043. var
  1044. n: integer;
  1045. begin
  1046. SHA1Context.Hi := 0;
  1047. SHA1Context.Lo := 0;
  1048. SHA1Context.Index := 0;
  1049. for n := 0 to High(SHA1Context.Buffer) do
  1050. SHA1Context.Buffer[n] := 0;
  1051. for n := 0 to High(SHA1Context.HashByte) do
  1052. SHA1Context.HashByte[n] := 0;
  1053. // FillChar(SHA1Context, SizeOf(TSHA1Ctx), #0);
  1054. SHA1Context.Hash[0] := integer($67452301);
  1055. SHA1Context.Hash[1] := integer($EFCDAB89);
  1056. SHA1Context.Hash[2] := integer($98BADCFE);
  1057. SHA1Context.Hash[3] := integer($10325476);
  1058. SHA1Context.Hash[4] := integer($C3D2E1F0);
  1059. end;
  1060. //******************************************************************************
  1061. function RB(A: integer): integer;
  1062. begin
  1063. Result := (A shr 24) or ((A shr 8) and $FF00) or ((A shl 8) and $FF0000) or (A shl 24);
  1064. end;
  1065. procedure SHA1Compress(var Data: TSHA1Ctx);
  1066. var
  1067. A, B, C, D, E, T: integer;
  1068. W: array[0..79] of integer;
  1069. i: integer;
  1070. n: integer;
  1071. function F1(x, y, z: integer): integer;
  1072. begin
  1073. Result := z xor (x and (y xor z));
  1074. end;
  1075. function F2(x, y, z: integer): integer;
  1076. begin
  1077. Result := x xor y xor z;
  1078. end;
  1079. function F3(x, y, z: integer): integer;
  1080. begin
  1081. Result := (x and y) or (z and (x or y));
  1082. end;
  1083. function LRot32(X: integer; c: integer): integer;
  1084. begin
  1085. result := (x shl c) or (x shr (32 - c));
  1086. end;
  1087. begin
  1088. ArrByteToLong(Data.Buffer, W);
  1089. // Move(Data.Buffer, W, Sizeof(Data.Buffer));
  1090. for i := 0 to 15 do
  1091. W[i] := RB(W[i]);
  1092. for i := 16 to 79 do
  1093. W[i] := LRot32(W[i-3] xor W[i-8] xor W[i-14] xor W[i-16], 1);
  1094. A := Data.Hash[0];
  1095. B := Data.Hash[1];
  1096. C := Data.Hash[2];
  1097. D := Data.Hash[3];
  1098. E := Data.Hash[4];
  1099. for i := 0 to 19 do
  1100. begin
  1101. T := LRot32(A, 5) + F1(B, C, D) + E + W[i] + integer($5A827999);
  1102. E := D;
  1103. D := C;
  1104. C := LRot32(B, 30);
  1105. B := A;
  1106. A := T;
  1107. end;
  1108. for i := 20 to 39 do
  1109. begin
  1110. T := LRot32(A, 5) + F2(B, C, D) + E + W[i] + integer($6ED9EBA1);
  1111. E := D;
  1112. D := C;
  1113. C := LRot32(B, 30);
  1114. B := A;
  1115. A := T;
  1116. end;
  1117. for i := 40 to 59 do
  1118. begin
  1119. T := LRot32(A, 5) + F3(B, C, D) + E + W[i] + integer($8F1BBCDC);
  1120. E := D;
  1121. D := C;
  1122. C := LRot32(B, 30);
  1123. B := A;
  1124. A := T;
  1125. end;
  1126. for i := 60 to 79 do
  1127. begin
  1128. T := LRot32(A, 5) + F2(B, C, D) + E + W[i] + integer($CA62C1D6);
  1129. E := D;
  1130. D := C;
  1131. C := LRot32(B, 30);
  1132. B := A;
  1133. A := T;
  1134. end;
  1135. Data.Hash[0] := Data.Hash[0] + A;
  1136. Data.Hash[1] := Data.Hash[1] + B;
  1137. Data.Hash[2] := Data.Hash[2] + C;
  1138. Data.Hash[3] := Data.Hash[3] + D;
  1139. Data.Hash[4] := Data.Hash[4] + E;
  1140. for n := 0 to high(w) do
  1141. w[n] := 0;
  1142. // FillChar(W, Sizeof(W), 0);
  1143. for n := 0 to high(Data.Buffer) do
  1144. Data.Buffer[n] := 0;
  1145. // FillChar(Data.Buffer, Sizeof(Data.Buffer), 0);
  1146. end;
  1147. //******************************************************************************
  1148. procedure SHA1Update(var Context: TSHA1Ctx; const Data: AnsiString);
  1149. var
  1150. Len: integer;
  1151. n: integer;
  1152. i, k: integer;
  1153. begin
  1154. Len := Length(data);
  1155. for k := 0 to 7 do
  1156. begin
  1157. i := Context.Lo;
  1158. Inc(Context.Lo, Len);
  1159. if Context.Lo < i then
  1160. Inc(Context.Hi);
  1161. end;
  1162. for n := 1 to len do
  1163. begin
  1164. Context.Buffer[Context.Index] := byte(Data[n]);
  1165. Inc(Context.Index);
  1166. if Context.Index = 64 then
  1167. begin
  1168. Context.Index := 0;
  1169. SHA1Compress(Context);
  1170. end;
  1171. end;
  1172. end;
  1173. //******************************************************************************
  1174. function SHA1Final(var Context: TSHA1Ctx): AnsiString;
  1175. type
  1176. Pinteger = ^integer;
  1177. var
  1178. i: integer;
  1179. procedure ItoArr(var Ar: Array of byte; I, value: Integer);
  1180. begin
  1181. Ar[i + 0] := Value and $000000FF;
  1182. Ar[i + 1] := (Value shr 8) and $000000FF;
  1183. Ar[i + 2] := (Value shr 16) and $000000FF;
  1184. Ar[i + 3] := (Value shr 24) and $000000FF;
  1185. end;
  1186. begin
  1187. Context.Buffer[Context.Index] := $80;
  1188. if Context.Index >= 56 then
  1189. SHA1Compress(Context);
  1190. ItoArr(Context.Buffer, 56, RB(Context.Hi));
  1191. ItoArr(Context.Buffer, 60, RB(Context.Lo));
  1192. // Pinteger(@Context.Buffer[56])^ := RB(Context.Hi);
  1193. // Pinteger(@Context.Buffer[60])^ := RB(Context.Lo);
  1194. SHA1Compress(Context);
  1195. Context.Hash[0] := RB(Context.Hash[0]);
  1196. Context.Hash[1] := RB(Context.Hash[1]);
  1197. Context.Hash[2] := RB(Context.Hash[2]);
  1198. Context.Hash[3] := RB(Context.Hash[3]);
  1199. Context.Hash[4] := RB(Context.Hash[4]);
  1200. ArrLongToByte(Context.Hash, Context.HashByte);
  1201. Result := '';
  1202. for i := 0 to 19 do
  1203. Result := Result + AnsiChar(Context.HashByte[i]);
  1204. end;
  1205. function SHA1(const Value: AnsiString): AnsiString;
  1206. var
  1207. SHA1Context: TSHA1Ctx;
  1208. begin
  1209. SHA1Init(SHA1Context);
  1210. SHA1Update(SHA1Context, Value);
  1211. Result := SHA1Final(SHA1Context);
  1212. end;
  1213. {==============================================================================}
  1214. function HMAC_SHA1(Text, Key: AnsiString): AnsiString;
  1215. var
  1216. ipad, opad, s: AnsiString;
  1217. n: Integer;
  1218. SHA1Context: TSHA1Ctx;
  1219. begin
  1220. if Length(Key) > 64 then
  1221. Key := SHA1(Key);
  1222. ipad := StringOfChar(#$36, 64);
  1223. opad := StringOfChar(#$5C, 64);
  1224. for n := 1 to Length(Key) do
  1225. begin
  1226. ipad[n] := AnsiChar(Byte(ipad[n]) xor Byte(Key[n]));
  1227. opad[n] := AnsiChar(Byte(opad[n]) xor Byte(Key[n]));
  1228. end;
  1229. SHA1Init(SHA1Context);
  1230. SHA1Update(SHA1Context, ipad);
  1231. SHA1Update(SHA1Context, Text);
  1232. s := SHA1Final(SHA1Context);
  1233. SHA1Init(SHA1Context);
  1234. SHA1Update(SHA1Context, opad);
  1235. SHA1Update(SHA1Context, s);
  1236. Result := SHA1Final(SHA1Context);
  1237. end;
  1238. {==============================================================================}
  1239. function SHA1LongHash(const Value: AnsiString; Len: integer): AnsiString;
  1240. var
  1241. cnt, rest: integer;
  1242. l: integer;
  1243. n: integer;
  1244. SHA1Context: TSHA1Ctx;
  1245. begin
  1246. l := length(Value);
  1247. cnt := Len div l;
  1248. rest := Len mod l;
  1249. SHA1Init(SHA1Context);
  1250. for n := 1 to cnt do
  1251. SHA1Update(SHA1Context, Value);
  1252. if rest > 0 then
  1253. SHA1Update(SHA1Context, Copy(Value, 1, rest));
  1254. Result := SHA1Final(SHA1Context);
  1255. end;
  1256. {==============================================================================}
  1257. procedure MD4Transform(var Buf: array of LongInt; const Data: array of LongInt);
  1258. var
  1259. A, B, C, D: LongInt;
  1260. function LRot32(a, b: longint): longint;
  1261. begin
  1262. Result:= (a shl b) or (a shr (32 - b));
  1263. end;
  1264. begin
  1265. A := Buf[0];
  1266. B := Buf[1];
  1267. C := Buf[2];
  1268. D := Buf[3];
  1269. A:= LRot32(A + (D xor (B and (C xor D))) + Data[ 0], 3);
  1270. D:= LRot32(D + (C xor (A and (B xor C))) + Data[ 1], 7);
  1271. C:= LRot32(C + (B xor (D and (A xor B))) + Data[ 2], 11);
  1272. B:= LRot32(B + (A xor (C and (D xor A))) + Data[ 3], 19);
  1273. A:= LRot32(A + (D xor (B and (C xor D))) + Data[ 4], 3);
  1274. D:= LRot32(D + (C xor (A and (B xor C))) + Data[ 5], 7);
  1275. C:= LRot32(C + (B xor (D and (A xor B))) + Data[ 6], 11);
  1276. B:= LRot32(B + (A xor (C and (D xor A))) + Data[ 7], 19);
  1277. A:= LRot32(A + (D xor (B and (C xor D))) + Data[ 8], 3);
  1278. D:= LRot32(D + (C xor (A and (B xor C))) + Data[ 9], 7);
  1279. C:= LRot32(C + (B xor (D and (A xor B))) + Data[10], 11);
  1280. B:= LRot32(B + (A xor (C and (D xor A))) + Data[11], 19);
  1281. A:= LRot32(A + (D xor (B and (C xor D))) + Data[12], 3);
  1282. D:= LRot32(D + (C xor (A and (B xor C))) + Data[13], 7);
  1283. C:= LRot32(C + (B xor (D and (A xor B))) + Data[14], 11);
  1284. B:= LRot32(B + (A xor (C and (D xor A))) + Data[15], 19);
  1285. A:= LRot32(A + ((B and C) or (B and D) or (C and D)) + Data[ 0] + longint($5a827999), 3);
  1286. D:= LRot32(D + ((A and B) or (A and C) or (B and C)) + Data[ 4] + longint($5a827999), 5);
  1287. C:= LRot32(C + ((D and A) or (D and B) or (A and B)) + Data[ 8] + longint($5a827999), 9);
  1288. B:= LRot32(B + ((C and D) or (C and A) or (D and A)) + Data[12] + longint($5a827999), 13);
  1289. A:= LRot32(A + ((B and C) or (B and D) or (C and D)) + Data[ 1] + longint($5a827999), 3);
  1290. D:= LRot32(D + ((A and B) or (A and C) or (B and C)) + Data[ 5] + longint($5a827999), 5);
  1291. C:= LRot32(C + ((D and A) or (D and B) or (A and B)) + Data[ 9] + longint($5a827999), 9);
  1292. B:= LRot32(B + ((C and D) or (C and A) or (D and A)) + Data[13] + longint($5a827999), 13);
  1293. A:= LRot32(A + ((B and C) or (B and D) or (C and D)) + Data[ 2] + longint($5a827999), 3);
  1294. D:= LRot32(D + ((A and B) or (A and C) or (B and C)) + Data[ 6] + longint($5a827999), 5);
  1295. C:= LRot32(C + ((D and A) or (D and B) or (A and B)) + Data[10] + longint($5a827999), 9);
  1296. B:= LRot32(B + ((C and D) or (C and A) or (D and A)) + Data[14] + longint($5a827999), 13);
  1297. A:= LRot32(A + ((B and C) or (B and D) or (C and D)) + Data[ 3] + longint($5a827999), 3);
  1298. D:= LRot32(D + ((A and B) or (A and C) or (B and C)) + Data[ 7] + longint($5a827999), 5);
  1299. C:= LRot32(C + ((D and A) or (D and B) or (A and B)) + Data[11] + longint($5a827999), 9);
  1300. B:= LRot32(B + ((C and D) or (C and A) or (D and A)) + Data[15] + longint($5a827999), 13);
  1301. A:= LRot32(A + (B xor C xor D) + Data[ 0] + longint($6ed9eba1), 3);
  1302. D:= LRot32(D + (A xor B xor C) + Data[ 8] + longint($6ed9eba1), 9);
  1303. C:= LRot32(C + (D xor A xor B) + Data[ 4] + longint($6ed9eba1), 11);
  1304. B:= LRot32(B + (C xor D xor A) + Data[12] + longint($6ed9eba1), 15);
  1305. A:= LRot32(A + (B xor C xor D) + Data[ 2] + longint($6ed9eba1), 3);
  1306. D:= LRot32(D + (A xor B xor C) + Data[10] + longint($6ed9eba1), 9);
  1307. C:= LRot32(C + (D xor A xor B) + Data[ 6] + longint($6ed9eba1), 11);
  1308. B:= LRot32(B + (C xor D xor A) + Data[14] + longint($6ed9eba1), 15);
  1309. A:= LRot32(A + (B xor C xor D) + Data[ 1] + longint($6ed9eba1), 3);
  1310. D:= LRot32(D + (A xor B xor C) + Data[ 9] + longint($6ed9eba1), 9);
  1311. C:= LRot32(C + (D xor A xor B) + Data[ 5] + longint($6ed9eba1), 11);
  1312. B:= LRot32(B + (C xor D xor A) + Data[13] + longint($6ed9eba1), 15);
  1313. A:= LRot32(A + (B xor C xor D) + Data[ 3] + longint($6ed9eba1), 3);
  1314. D:= LRot32(D + (A xor B xor C) + Data[11] + longint($6ed9eba1), 9);
  1315. C:= LRot32(C + (D xor A xor B) + Data[ 7] + longint($6ed9eba1), 11);
  1316. B:= LRot32(B + (C xor D xor A) + Data[15] + longint($6ed9eba1), 15);
  1317. Inc(Buf[0], A);
  1318. Inc(Buf[1], B);
  1319. Inc(Buf[2], C);
  1320. Inc(Buf[3], D);
  1321. end;
  1322. {==============================================================================}
  1323. function MD4(const Value: AnsiString): AnsiString;
  1324. var
  1325. MDContext: TMDCtx;
  1326. begin
  1327. MDInit(MDContext);
  1328. MDUpdate(MDContext, Value, @MD4Transform);
  1329. Result := MDFinal(MDContext, @MD4Transform);
  1330. end;
  1331. {==============================================================================}
  1332. end.