├── LICENSE ├── MD5.pas ├── PdfPageCount.pas └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /MD5.pas: -------------------------------------------------------------------------------- 1 | unit MD5; 2 | 3 | (******************************************************************************* 4 | * * 5 | * Author : Angus Johnson * 6 | * Version : 1.2 * 7 | * Date : 12 February 2024 * 8 | * Website : http://www.angusj.com * 9 | * Copyright : Angus Johnson 2010-2024 * 10 | * * 11 | * License: * 12 | * Use, modification & distribution is subject to Boost Software License Ver 1. * 13 | * http://www.boost.org/LICENSE_1_0.txt * 14 | * * 15 | *******************************************************************************) 16 | 17 | interface 18 | 19 | {$Q-} 20 | 21 | uses 22 | Windows, SysUtils, Classes; 23 | 24 | const 25 | BuffLen64 = 64; 26 | 27 | type 28 | {$IFNDEF UNICODE} 29 | PByte = PChar; 30 | {$ENDIF} 31 | PByteArray = ^TByteArray; 32 | TByteArray = array[0..MaxInt-1] of Byte; 33 | TByteArray16 = array [0..15] of Byte; 34 | 35 | Md5Record = record 36 | private 37 | state : array [0..3] of cardinal; 38 | count : array [0..1] of cardinal; 39 | digest : TByteArray16; 40 | buffer64 : array [0..BuffLen64 -1] of Byte; 41 | procedure Transform; 42 | 43 | procedure F1(var a: cardinal; b, c, d, x, s: cardinal); 44 | procedure F2(var a: cardinal; b, c, d, x, s: cardinal); 45 | procedure F3(var a: cardinal; b, c, d, x, s: cardinal); 46 | procedure F4(var a: cardinal; b, c, d, x, s: cardinal); 47 | public 48 | procedure Init; 49 | procedure Update(start: PByteArray; length: cardinal); 50 | procedure Finalize; 51 | property Hash: TByteArray16 read digest; 52 | end; 53 | 54 | implementation 55 | 56 | //------------------------------------------------------------------------------ 57 | //------------------------------------------------------------------------------ 58 | 59 | procedure Md5Record.Init; 60 | begin 61 | count[0] := 0; 62 | count[1] := 0; 63 | 64 | //Load magic constants ... 65 | state[0] := $67452301; 66 | state[1] := $efcdab89; 67 | state[2] := $98badcfe; 68 | state[3] := $10325476; 69 | end; 70 | //------------------------------------------------------------------------------ 71 | 72 | procedure Md5Record.Finalize; 73 | var 74 | cnt: cardinal; 75 | pb : system.PByte; 76 | begin 77 | cnt := (count[0] shr 3) and $3f; 78 | pb := @buffer64[cnt]; 79 | pb^ := $80; 80 | inc(pb); 81 | cnt := 63 - cnt; 82 | if cnt < 8 then 83 | begin 84 | // Two lots of padding: Pad the first block to 64 bytes */ 85 | FillChar(pb^, cnt, 0); 86 | Transform; 87 | // Now fill the next block with 56 bytes */ 88 | FillChar(buffer64[0], 56, 0); 89 | end 90 | else if cnt > 8 then 91 | FillChar(pb^, cnt -8, 0); 92 | 93 | // Append length in bits and transform ... 94 | move(count[0], buffer64[56], 4); 95 | move(count[1], buffer64[60], 4); 96 | Transform; 97 | move(state[0], digest[0], 16); 98 | end; 99 | //------------------------------------------------------------------------------ 100 | 101 | procedure Md5Record.Transform; 102 | var 103 | a,b,c,d: cardinal; 104 | x: array[0..15] of cardinal; 105 | begin 106 | Move(buffer64[0], x[0], BuffLen64); 107 | a := state[0]; b := state[1]; c := state[2]; d := state[3]; 108 | 109 | // Round 1 ... 110 | F1 (a, b, c, d, x[ 0] + $d76aa478, 7); 111 | F1 (d, a, b, c, x[ 1] + $e8c7b756, 12); 112 | F1 (c, d, a, b, x[ 2] + $242070db, 17); 113 | F1 (b, c, d, a, x[ 3] + $c1bdceee, 22); 114 | F1 (a, b, c, d, x[ 4] + $f57c0faf, 7); 115 | F1 (d, a, b, c, x[ 5] + $4787c62a, 12); 116 | F1 (c, d, a, b, x[ 6] + $a8304613, 17); 117 | F1 (b, c, d, a, x[ 7] + $fd469501, 22); 118 | F1 (a, b, c, d, x[ 8] + $698098d8, 7); 119 | F1 (d, a, b, c, x[ 9] + $8b44f7af, 12); 120 | F1 (c, d, a, b, x[10] + $ffff5bb1, 17); 121 | F1 (b, c, d, a, x[11] + $895cd7be, 22); 122 | F1 (a, b, c, d, x[12] + $6b901122, 7); 123 | F1 (d, a, b, c, x[13] + $fd987193, 12); 124 | F1 (c, d, a, b, x[14] + $a679438e, 17); 125 | F1 (b, c, d, a, x[15] + $49b40821, 22); 126 | 127 | // Round 2 ... 128 | F2 (a, b, c, d, x[ 1] + $f61e2562, 5); 129 | F2 (d, a, b, c, x[ 6] + $c040b340, 9); 130 | F2 (c, d, a, b, x[11] + $265e5a51, 14); 131 | F2 (b, c, d, a, x[ 0] + $e9b6c7aa, 20); 132 | F2 (a, b, c, d, x[ 5] + $d62f105d, 5); 133 | F2 (d, a, b, c, x[10] + $02441453, 9); 134 | F2 (c, d, a, b, x[15] + $d8a1e681, 14); 135 | F2 (b, c, d, a, x[ 4] + $e7d3fbc8, 20); 136 | F2 (a, b, c, d, x[ 9] + $21e1cde6, 5); 137 | F2 (d, a, b, c, x[14] + $c33707d6, 9); 138 | F2 (c, d, a, b, x[ 3] + $f4d50d87, 14); 139 | F2 (b, c, d, a, x[ 8] + $455a14ed, 20); 140 | F2 (a, b, c, d, x[13] + $a9e3e905, 5); 141 | F2 (d, a, b, c, x[ 2] + $fcefa3f8, 9); 142 | F2 (c, d, a, b, x[ 7] + $676f02d9, 14); 143 | F2 (b, c, d, a, x[12] + $8d2a4c8a, 20); 144 | 145 | // Round 3 .. 146 | F3 (a, b, c, d, x[ 5] + $fffa3942, 4); 147 | F3 (d, a, b, c, x[ 8] + $8771f681, 11); 148 | F3 (c, d, a, b, x[11] + $6d9d6122, 16); 149 | F3 (b, c, d, a, x[14] + $fde5380c, 23); 150 | F3 (a, b, c, d, x[ 1] + $a4beea44, 4); 151 | F3 (d, a, b, c, x[ 4] + $4bdecfa9, 11); 152 | F3 (c, d, a, b, x[ 7] + $f6bb4b60, 16); 153 | F3 (b, c, d, a, x[10] + $bebfbc70, 23); 154 | F3 (a, b, c, d, x[13] + $289b7ec6, 4); 155 | F3 (d, a, b, c, x[ 0] + $eaa127fa, 11); 156 | F3 (c, d, a, b, x[ 3] + $d4ef3085, 16); 157 | F3 (b, c, d, a, x[ 6] + $4881d05, 23); 158 | F3 (a, b, c, d, x[ 9] + $d9d4d039, 4); 159 | F3 (d, a, b, c, x[12] + $e6db99e5, 11); 160 | F3 (c, d, a, b, x[15] + $1fa27cf8, 16); 161 | F3 (b, c, d, a, x[ 2] + $c4ac5665, 23); 162 | 163 | // Round 4 .. 164 | F4 (a, b, c, d, x[ 0] + $f4292244, 6); 165 | F4 (d, a, b, c, x[ 7] + $432aff97, 10); 166 | F4 (c, d, a, b, x[14] + $ab9423a7, 15); 167 | F4 (b, c, d, a, x[ 5] + $fc93a039, 21); 168 | F4 (a, b, c, d, x[12] + $655b59c3, 6); 169 | F4 (d, a, b, c, x[ 3] + $8f0ccc92, 10); 170 | F4 (c, d, a, b, x[10] + $ffeff47d, 15); 171 | F4 (b, c, d, a, x[ 1] + $85845dd1, 21); 172 | F4 (a, b, c, d, x[ 8] + $6fa87e4f, 6); 173 | F4 (d, a, b, c, x[15] + $fe2ce6e0, 10); 174 | F4 (c, d, a, b, x[ 6] + $a3014314, 15); 175 | F4 (b, c, d, a, x[13] + $4e0811a1, 21); 176 | F4 (a, b, c, d, x[ 4] + $f7537e82, 6); 177 | F4 (d, a, b, c, x[11] + $bd3af235, 10); 178 | F4 (c, d, a, b, x[ 2] + $2ad7d2bb, 15); 179 | F4 (b, c, d, a, x[ 9] + $eb86d391, 21); 180 | 181 | inc(state[0], a); 182 | inc(state[1], b); 183 | inc(state[2], c); 184 | inc(state[3], d); 185 | end; 186 | //------------------------------------------------------------------------------ 187 | 188 | procedure Md5Record.Update(start: PByteArray; length: cardinal); 189 | var 190 | t, idx, spc: cardinal; 191 | //sl: TStringList; 192 | begin 193 | 194 | // Update number of bits 195 | t := count[0]; 196 | count[0] := t + (length shl 3); 197 | if count[0] < t then inc(count[1]); 198 | inc(count[1], length shr 29); 199 | 200 | // Compute number of bytes mod 64 201 | idx := (t shr 3) and $3f; 202 | spc := BuffLen64 - idx; 203 | 204 | if idx > 0 then 205 | begin 206 | if (length < spc) then 207 | begin 208 | move(start^, buffer64[idx], length); 209 | exit; 210 | end; 211 | move(start^, buffer64[idx], spc); 212 | Transform; 213 | dec(length, spc); 214 | inc(PByte(start), spc); 215 | end; 216 | 217 | //Process data in 64-byte chunks ... 218 | while (length >= BuffLen64) do 219 | begin 220 | move(start^, buffer64[0], BuffLen64); 221 | Transform; 222 | dec(length, BuffLen64); 223 | inc(PByte(start), BuffLen64); 224 | end; 225 | 226 | //Finally, handle any remaining bytes of data ... 227 | move(start^, buffer64[0], length); 228 | end; 229 | //------------------------------------------------------------------------------ 230 | 231 | procedure Md5Record.F1(var a: cardinal; b, c, d, x, s: cardinal); 232 | begin 233 | inc(a, (d xor (b and (c xor d))) + x); 234 | a := ((a shl s) or (a shr (32-s))) + b; 235 | end; 236 | //------------------------------------------------------------------------------ 237 | 238 | procedure Md5Record.F2(var a: cardinal; b, c, d, x, s: cardinal); 239 | begin 240 | inc(a, ((b and d) or (c and not d)) + x); 241 | a := ((a shl s) or (a shr (32-s))) + b; 242 | end; 243 | //------------------------------------------------------------------------------ 244 | 245 | procedure Md5Record.F3(var a: cardinal; b, c, d, x, s: cardinal); 246 | begin 247 | inc(a, (b xor c xor d) + x); 248 | a := ((a shl s) or (a shr (32-s))) + b; 249 | end; 250 | //------------------------------------------------------------------------------ 251 | 252 | procedure Md5Record.F4(var a: cardinal; b, c, d, x, s: cardinal); 253 | begin 254 | inc(a, (c xor (b or not d)) + x); 255 | a := ((a shl s) or (a shr (32-s))) + b; 256 | end; 257 | //------------------------------------------------------------------------------ 258 | 259 | end. 260 | -------------------------------------------------------------------------------- /PdfPageCount.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngusJohnson/PdfPageCount/4f25cbc02d898e0f0ae7b185ee57a92350f94459/PdfPageCount.pas -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PdfPageCount (Delphi only) 2 | 3 | **Limitation**: The PdfPageCount function will return -1 (no result) whenever PDF files are encrypted (ie have access protection).

4 | 5 | While this code isn't polished, it's quite functional. 6 | --------------------------------------------------------------------------------