141 void ToHex (
const UCHAR In[16],
char *Out,
int LowerCase);
163 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
164 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
165 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
168 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
169 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
170 #define H(x, y, z) ((x) ^ (y) ^ (z))
171 #define I(x, y, z) ((y) ^ ((x) | (~z)))
175 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
178 #define FF(a, b, c, d, x, s, ac) { \
179 (a) = ROTATE_LEFT((a) + F((b), (c), (d)) + (x) + (UINT32)(ac), (s)) + (b); }
180 #define GG(a, b, c, d, x, s, ac) { \
181 (a) = ROTATE_LEFT((a) + G((b), (c), (d)) + (x) + (UINT32)(ac), (s)) + (b); }
182 #define HH(a, b, c, d, x, s, ac) { \
183 (a) = ROTATE_LEFT((a) + H((b), (c), (d)) + (x) + (UINT32)(ac), (s)) + (b); }
184 #define II(a, b, c, d, x, s, ac) { \
185 (a) = ROTATE_LEFT((a) + I((b), (c), (d)) + (x) + (UINT32)(ac), (s)) + (b); }
188 #define BUFFER_LEN 1024
195 context->
count[0] = 0;
196 context->
count[1] = 0;
197 context->
state[0] = 0x67452301;
198 context->
state[1] = 0xefcdab89;
199 context->
state[2] = 0x98badcfe;
200 context->
state[3] = 0x10325476;
211 index = (
UINT)((context->
count[0] >> 3) & 0x3F);
219 partLen = 64 - index;
222 if (inputLen >= partLen) {
226 inputLenM63 = inputLen - 63;
227 for (i = partLen; i < inputLenM63; i += 64) {
253 index = (
UINT)((context->
count[0] >> 3) & 0x3f);
254 padLen = (index < 56) ? (56 - index) : (120 - index);
282 x[0] = ( (
UINT32)block[0]) | (((
UINT32)block[1]) << 8) |
283 (((
UINT32)block[2]) << 16) | (((
UINT32)block[3]) << 24);
284 x[1] = ( (
UINT32)block[4]) | (((
UINT32)block[5]) << 8) |
285 (((
UINT32)block[6]) << 16) | (((
UINT32)block[7]) << 24);
286 x[2] = ( (
UINT32)block[8]) | (((
UINT32)block[9]) << 8) |
287 (((
UINT32)block[10]) << 16) | (((
UINT32)block[11]) << 24);
288 x[3] = ( (
UINT32)block[12]) | (((
UINT32)block[13]) << 8) |
289 (((
UINT32)block[14]) << 16) | (((
UINT32)block[15]) << 24);
290 x[4] = ( (
UINT32)block[16]) | (((
UINT32)block[17]) << 8) |
291 (((
UINT32)block[18]) << 16) | (((
UINT32)block[19]) << 24);
292 x[5] = ( (
UINT32)block[20]) | (((
UINT32)block[21]) << 8) |
293 (((
UINT32)block[22]) << 16) | (((
UINT32)block[23]) << 24);
294 x[6] = ( (
UINT32)block[24]) | (((
UINT32)block[25]) << 8) |
295 (((
UINT32)block[26]) << 16) | (((
UINT32)block[27]) << 24);
296 x[7] = ( (
UINT32)block[28]) | (((
UINT32)block[29]) << 8) |
297 (((
UINT32)block[30]) << 16) | (((
UINT32)block[31]) << 24);
298 x[8] = ( (
UINT32)block[32]) | (((
UINT32)block[33]) << 8) |
299 (((
UINT32)block[34]) << 16) | (((
UINT32)block[35]) << 24);
300 x[9] = ( (
UINT32)block[36]) | (((
UINT32)block[37]) << 8) |
301 (((
UINT32)block[38]) << 16) | (((
UINT32)block[39]) << 24);
302 x[10] = ( (
UINT32)block[40]) | (((
UINT32)block[41]) << 8) |
303 (((
UINT32)block[42]) << 16) | (((
UINT32)block[43]) << 24);
304 x[11] = ( (
UINT32)block[44]) | (((
UINT32)block[45]) << 8) |
305 (((
UINT32)block[46]) << 16) | (((
UINT32)block[47]) << 24);
306 x[12] = ( (
UINT32)block[48]) | (((
UINT32)block[49]) << 8) |
307 (((
UINT32)block[50]) << 16) | (((
UINT32)block[51]) << 24);
308 x[13] = ( (
UINT32)block[52]) | (((
UINT32)block[53]) << 8) |
309 (((
UINT32)block[54]) << 16) | (((
UINT32)block[55]) << 24);
310 x[14] = ( (
UINT32)block[56]) | (((
UINT32)block[57]) << 8) |
311 (((
UINT32)block[58]) << 16) | (((
UINT32)block[59]) << 24);
312 x[15] = ( (
UINT32)block[60]) | (((
UINT32)block[61]) << 8) |
313 (((
UINT32)block[62]) << 16) | (((
UINT32)block[63]) << 24);
316 FF(a, b, c, d, x[ 0],
S11, 0xd76aa478);
317 FF(d, a, b, c, x[ 1],
S12, 0xe8c7b756);
318 FF(c, d, a, b, x[ 2],
S13, 0x242070db);
319 FF(b, c, d, a, x[ 3],
S14, 0xc1bdceee);
320 FF(a, b, c, d, x[ 4],
S11, 0xf57c0faf);
321 FF(d, a, b, c, x[ 5],
S12, 0x4787c62a);
322 FF(c, d, a, b, x[ 6],
S13, 0xa8304613);
323 FF(b, c, d, a, x[ 7],
S14, 0xfd469501);
324 FF(a, b, c, d, x[ 8],
S11, 0x698098d8);
325 FF(d, a, b, c, x[ 9],
S12, 0x8b44f7af);
326 FF(c, d, a, b, x[10],
S13, 0xffff5bb1);
327 FF(b, c, d, a, x[11],
S14, 0x895cd7be);
328 FF(a, b, c, d, x[12],
S11, 0x6b901122);
329 FF(d, a, b, c, x[13],
S12, 0xfd987193);
330 FF(c, d, a, b, x[14],
S13, 0xa679438e);
331 FF(b, c, d, a, x[15],
S14, 0x49b40821);
334 GG(a, b, c, d, x[ 1],
S21, 0xf61e2562);
335 GG(d, a, b, c, x[ 6],
S22, 0xc040b340);
336 GG(c, d, a, b, x[11],
S23, 0x265e5a51);
337 GG(b, c, d, a, x[ 0],
S24, 0xe9b6c7aa);
338 GG(a, b, c, d, x[ 5],
S21, 0xd62f105d);
339 GG(d, a, b, c, x[10],
S22, 0x2441453);
340 GG(c, d, a, b, x[15],
S23, 0xd8a1e681);
341 GG(b, c, d, a, x[ 4],
S24, 0xe7d3fbc8);
342 GG(a, b, c, d, x[ 9],
S21, 0x21e1cde6);
343 GG(d, a, b, c, x[14],
S22, 0xc33707d6);
344 GG(c, d, a, b, x[ 3],
S23, 0xf4d50d87);
346 GG(b, c, d, a, x[ 8],
S24, 0x455a14ed);
347 GG(a, b, c, d, x[13],
S21, 0xa9e3e905);
348 GG(d, a, b, c, x[ 2],
S22, 0xfcefa3f8);
349 GG(c, d, a, b, x[ 7],
S23, 0x676f02d9);
350 GG(b, c, d, a, x[12],
S24, 0x8d2a4c8a);
353 HH(a, b, c, d, x[ 5],
S31, 0xfffa3942);
354 HH(d, a, b, c, x[ 8],
S32, 0x8771f681);
355 HH(c, d, a, b, x[11],
S33, 0x6d9d6122);
356 HH(b, c, d, a, x[14],
S34, 0xfde5380c);
357 HH(a, b, c, d, x[ 1],
S31, 0xa4beea44);
358 HH(d, a, b, c, x[ 4],
S32, 0x4bdecfa9);
359 HH(c, d, a, b, x[ 7],
S33, 0xf6bb4b60);
360 HH(b, c, d, a, x[10],
S34, 0xbebfbc70);
361 HH(a, b, c, d, x[13],
S31, 0x289b7ec6);
362 HH(d, a, b, c, x[ 0],
S32, 0xeaa127fa);
363 HH(c, d, a, b, x[ 3],
S33, 0xd4ef3085);
364 HH(b, c, d, a, x[ 6],
S34, 0x4881d05);
365 HH(a, b, c, d, x[ 9],
S31, 0xd9d4d039);
366 HH(d, a, b, c, x[12],
S32, 0xe6db99e5);
367 HH(c, d, a, b, x[15],
S33, 0x1fa27cf8);
368 HH(b, c, d, a, x[ 2],
S34, 0xc4ac5665);
371 II(a, b, c, d, x[ 0],
S41, 0xf4292244);
372 II(d, a, b, c, x[ 7],
S42, 0x432aff97);
373 II(c, d, a, b, x[14],
S43, 0xab9423a7);
374 II(b, c, d, a, x[ 5],
S44, 0xfc93a039);
375 II(a, b, c, d, x[12],
S41, 0x655b59c3);
376 II(d, a, b, c, x[ 3],
S42, 0x8f0ccc92);
377 II(c, d, a, b, x[10],
S43, 0xffeff47d);
378 II(b, c, d, a, x[ 1],
S44, 0x85845dd1);
379 II(a, b, c, d, x[ 8],
S41, 0x6fa87e4f);
380 II(d, a, b, c, x[15],
S42, 0xfe2ce6e0);
381 II(c, d, a, b, x[ 6],
S43, 0xa3014314);
382 II(b, c, d, a, x[13],
S44, 0x4e0811a1);
383 II(a, b, c, d, x[ 4],
S41, 0xf7537e82);
384 II(d, a, b, c, x[11],
S42, 0xbd3af235);
385 II(c, d, a, b, x[ 2],
S43, 0x2ad7d2bb);
386 II(b, c, d, a, x[ 9],
S44, 0xeb86d391);
393 memset((
POINTER)x, 0,
sizeof(x));
401 for (j = 0; j < len; j++) {
402 *output++ = (
UCHAR)( *input & 0xff);
403 *output++ = (
UCHAR)((*input >> 8) & 0xff);
404 *output++ = (
UCHAR)((*input >> 16) & 0xff);
405 *output++ = (
UCHAR)((*input++ >> 24) & 0xff);
422 if (inputLen >> 31 != 0) {
423 mexErrMsgTxt(
"*** CalcMD5[mex]: Input > 2^31 byte not handled yet.");
426 arrayP = (
UCHAR *) array;
434 while (bufferP < bufferEnd) {
435 *bufferP++ = *arrayP;
445 bufferEnd =
buffer + Chunk;
447 while (bufferP < bufferEnd) {
448 *bufferP++ = *arrayP;
467 if (inputLen >> 31 != 0) {
468 mexErrMsgTxt(
"*** CalcMD5[mex]: Input > 2^31 byte not handled yet.");
485 if ((FID = fopen(filename,
"rb")) == NULL) {
486 mexPrintf(
"*** Error for file: [%s]\n", filename);
487 mexErrMsgTxt(
"*** CalcMD5[mex]: Cannot open file.");
495 if (allLen > 2147483647) {
497 mexErrMsgTxt(
"*** CalcMD5[mex]: Cannot handle files > 2.1GB yet.");
508 void ToHex(
const UCHAR digest[16],
char *output,
int LowerCase)
513 for (outputEnd = output + 32; output < outputEnd; output += 2) {
514 sprintf(output,
"%02x", *(digest++));
517 for (outputEnd = output + 32; output < outputEnd; output += 2) {
518 sprintf(output,
"%02X", *(digest++));
531 static const UCHAR B64[] =
532 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
540 for (i = 0; i < 5; i++) {
541 *p++ = B64[(*s >> 2) & 0x3F];
542 *p++ = B64[((*s & 0x3) << 4) | ((s[1] & 0xF0) >> 4)];
543 *p++ = B64[((s[1] & 0xF) << 2) | ((s[2] & 0xC0) >> 6)];
544 *p++ = B64[s[2] & 0x3F];
548 *p++ = B64[(*s >> 2) & 0x3F];
549 *p++ = B64[((*s & 0x3) << 4)];
556 void mexFunction(
int nlhs, mxArray *plhs[],
int nrhs,
const mxArray *prhs[])
563 char *FileName, InType, hexOut[33], b64Out[23];
564 UCHAR digest[16], *digestP, OutType =
'h';
565 int isFile =
false, isUnicode =
false;
566 double *outP, *outEnd;
569 if (nrhs == 0 || nrhs > 3) {
570 mexErrMsgTxt(
"*** CalcMD5[mex]: 1 to 3 inputs required.");
573 mexErrMsgTxt(
"*** CalcMD5[mex]: Too many output arguments.");
577 if (nrhs >= 2 && mxGetNumberOfElements(prhs[1]) > 0) {
578 if (mxIsChar(prhs[1]) == 0) {
579 mexErrMsgTxt(
"*** CalcMD5[mex]: 2nd input must be a string.");
582 InType = (
char) tolower(*(
POINTER) mxGetData(prhs[1]));
583 isFile = (InType ==
'f');
584 isUnicode = (InType ==
'u');
588 if (nrhs == 3 && !mxIsEmpty(prhs[2])) {
589 if (mxIsChar(prhs[2]) == 0) {
590 mexErrMsgTxt(
"*** CalcMD5[mex]: 3rd input must be a string.");
593 OutType = *(
POINTER) mxGetData(prhs[2]);
598 if ((FileName = mxArrayToString(prhs[0])) == NULL) {
599 mexErrMsgTxt(
"*** CalcMD5[mex]: Cannot get file name.");
604 }
else if (mxIsNumeric(prhs[0]) || isUnicode) {
606 mxGetNumberOfElements(prhs[0]) * mxGetElementSize(prhs[0]),
609 }
else if (mxIsChar(prhs[0])) {
610 MD5Char((mxChar *) mxGetData(prhs[0]),
611 mxGetNumberOfElements(prhs[0]),
615 mexErrMsgTxt(
"*** CalcMD5[mex]: Input type not accepted.");
622 ToHex(digest, hexOut, OutType ==
'h');
623 plhs[0] = mxCreateString(hexOut);
628 plhs[0] = mxCreateDoubleMatrix(1, 16, mxREAL);
629 outP = mxGetPr(plhs[0]);
631 for (outEnd = outP + 16; outP < outEnd; outP++) {
632 *outP = (
double) *digestP++;
641 plhs[0] = mxCreateString(b64Out);
645 mexErrMsgTxt(
"*** CalcMD5[mex]: Unknown output type.");
void MD5Encode(UCHAR *, UINT32 *, UINT)
void MD5Array(UCHAR *data, mwSize N, UCHAR digest[16])
void MD5File(char *FileName, UCHAR digest[16])
void ToBase64(const UCHAR In[16], char *Out)
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
#define II(a, b, c, d, x, s, ac)
static UCHAR buffer[BUFFER_LEN]
#define FF(a, b, c, d, x, s, ac)
void MD5Char(mxChar *data, mwSize N, UCHAR digest[16])
#define HH(a, b, c, d, x, s, ac)
void MD5Update(MD5_CTX *, UCHAR *, UINT)
void MD5Transform(UINT32[4], UCHAR[64])
void ToHex(const UCHAR In[16], char *Out, int LowerCase)
void MD5Final(UCHAR[16], MD5_CTX *)
#define GG(a, b, c, d, x, s, ac)
A MatLab character array.