/*
* Copyright (C) 2006 Michael Niedermayer (michaelni@gmx.at)
* Copyright (C) 2003-2005 by Christopher R. Hertel (crh@ubiqx.mn.org)
- * #inlcude LGPL license
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* References:
* IETF RFC 1321: The MD5 Message-Digest Algorithm
* simplified, cleaned and IMO redundant comments removed by michael
*
* if you use gcc, then version 4.1 or later and -fomit-frame-pointer is
- * strongly recommanded
+ * strongly recommended
*/
#include "common.h"
uint8_t block[64];
uint32_t ABCD[4];
uint64_t len;
- int b_used;
} AVMD5;
const int av_md5_size= sizeof(AVMD5);
a += T[i];\
\
switch(i>>4){\
- case 0: a += (d ^ b&(c^d)) + X[ i &15 ]; break;\
- case 1: a += (c ^ d&(c^b)) + X[ (1+5*i)&15 ]; break;\
- case 2: a += (b^c^d) + X[ (5+3*i)&15 ]; break;\
- case 3: a += (c^(b|~d)) + X[ ( 7*i)&15 ]; break;\
+ case 0: a += (d ^ (b&(c^d))) + X[ i &15 ]; break;\
+ case 1: a += (c ^ (d&(c^b))) + X[ (1+5*i)&15 ]; break;\
+ case 2: a += (b^c^d) + X[ (5+3*i)&15 ]; break;\
+ case 3: a += (c^(b|~d)) + X[ ( 7*i)&15 ]; break;\
}\
a = b + (( a << t ) | ( a >> (32 - t) ));
-static void body(uint32_t ABCD[4], const uint32_t X[16]){
- int i, t;
+static void body(uint32_t ABCD[4], uint32_t X[16]){
+
+ int t;
+ int i attribute_unused;
unsigned int a= ABCD[3];
unsigned int b= ABCD[2];
unsigned int c= ABCD[1];
void av_md5_init(AVMD5 *ctx){
ctx->len = 0;
- ctx->b_used = 0;
ctx->ABCD[0] = 0x10325476;
ctx->ABCD[1] = 0x98badcfe;
}
void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len){
- int i;
+ int i, j;
+ j= ctx->len & 63;
ctx->len += len;
for( i = 0; i < len; i++ ){
- ctx->block[ ctx->b_used++ ] = src[i];
- if( 64 == ctx->b_used ){
- body(ctx->ABCD, (const uint32_t*) ctx->block);
- ctx->b_used = 0;
+ ctx->block[j++] = src[i];
+ if( 64 == j ){
+ body(ctx->ABCD, (uint32_t*) ctx->block);
+ j = 0;
}
}
}
void av_md5_final(AVMD5 *ctx, uint8_t *dst){
int i;
+ uint64_t finalcount= le2me_64(ctx->len<<3);
- ctx->block[ctx->b_used++] = 0x80;
-
- memset(&ctx->block[ctx->b_used], 0, 64 - ctx->b_used);
-
- if( 56 < ctx->b_used ){
- body( ctx->ABCD, (const uint32_t*) ctx->block );
- memset(ctx->block, 0, 64);
- }
-
- for(i=0; i<8; i++)
- ctx->block[56+i] = (ctx->len << 3) >> (i<<3);
+ av_md5_update(ctx, "\200", 1);
+ while((ctx->len & 63)<56)
+ av_md5_update(ctx, "", 1);
- body(ctx->ABCD, (const uint32_t*) ctx->block);
+ av_md5_update(ctx, &finalcount, 8);
for(i=0; i<4; i++)
((uint32_t*)dst)[i]= le2me_32(ctx->ABCD[3-i]);
#ifdef TEST
#include <stdio.h>
+#undef printf
main(){
uint64_t md5val;
int i;
uint8_t in[1000];
for(i=0; i<1000; i++) in[i]= i*i;
- av_md5_sum( (uint8_t*)&md5val, in, 1000); printf("%lld\n", md5val);
- av_md5_sum( (uint8_t*)&md5val, in, 63); printf("%lld\n", md5val);
- av_md5_sum( (uint8_t*)&md5val, in, 64); printf("%lld\n", md5val);
- av_md5_sum( (uint8_t*)&md5val, in, 65); printf("%lld\n", md5val);
+ av_md5_sum( (uint8_t*)&md5val, in, 1000); printf("%"PRId64"\n", md5val);
+ av_md5_sum( (uint8_t*)&md5val, in, 63); printf("%"PRId64"\n", md5val);
+ av_md5_sum( (uint8_t*)&md5val, in, 64); printf("%"PRId64"\n", md5val);
+ av_md5_sum( (uint8_t*)&md5val, in, 65); printf("%"PRId64"\n", md5val);
for(i=0; i<1000; i++) in[i]= i % 127;
- av_md5_sum( (uint8_t*)&md5val, in, 999); printf("%lld\n", md5val);
+ av_md5_sum( (uint8_t*)&md5val, in, 999); printf("%"PRId64"\n", md5val);
}
#endif