当前位置:网站首页>md5sum源码 可多平台编译
md5sum源码 可多平台编译
2022-08-01 17:17:00 【月上纱窗】
在ubuntu下,与系统自带的md5sum命令,测试1.6G的大文件,计算时间几乎一样,同为21.4s。
但是跟windows的“certutil -hashfile file MD5”命令的4s相比,还是太弱了。
/* md5sum.c - print MD5 Message-Digest Algorithm
* Copyright (C) 1995, 1996, 1998, 1999,
* 2000, 2001, 2002 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* According to the definition of MD5 in RFC 1321 from April 1992.
* NOTE: This is *not* the same file as the one from glibc.
*/
/* Written by Ulrich Drepper <[email protected]>, 1995. */
/* Heavily modified for GnuPG by <[email protected]> *//* Test values:
* "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E
* "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61
* "abc" 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72
* "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0
*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>#undef BIG_ENDIAN_HOST
typedef unsigned int u32;/****************
* Rotate a 32 bit integer by n bytes
*/
#if defined(__GNUC__) && defined(__i386__)
static inline u32
rol(u32 x, int n)
{
__asm__("roll %%cl,%0"
:"=r" (x)
: "0" (x), "c" (n));
return x;
}
#else
#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
#endiftypedef struct {
u32 A, B, C, D; /* chaining variables */
u32 nblocks;
unsigned char buf[64];
int count;
} MD5_CONTEXT;static void md5_init(MD5_CONTEXT* ctx)
{
ctx->A = 0x67452301;
ctx->B = 0xefcdab89;
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
ctx->nblocks = 0;
ctx->count = 0;
}/* These are the four functions used in the four steps of the MD5 algorithm
and defined in the RFC 1321. The first function is a little bit optimized
(as found in Colin Plumbs public domain implementation). */
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
#define FF(b, c, d) (d ^ (b & (c ^ d)))
#define FG(b, c, d) FF (d, b, c)
#define FH(b, c, d) (b ^ c ^ d)
#define FI(b, c, d) (c ^ (b | ~d))/****************
* transform n*64 bytes
*/
static void transform(MD5_CONTEXT* ctx, unsigned char* data)
{
u32 correct_words[16];
u32 A = ctx->A;
u32 B = ctx->B;
u32 C = ctx->C;
u32 D = ctx->D;
u32* cwp = correct_words;
#ifdef BIG_ENDIAN_HOST
{ int i;
unsigned char* p2, * p1;
for (i = 0, p1 = data, p2 = (unsigned char*)correct_words; i < 16; i++, p2 += 4) {
p2[3] = *p1++;
p2[2] = *p1++;
p2[1] = *p1++;
p2[0] = *p1++;
}
}
#else
memcpy(correct_words, data, 64);
#endif
#define OP(a, b, c, d, s, T) \
do \
{ \
a += FF (b, c, d) + (*cwp++) + T; \
a = rol(a, s); \
a += b; \
} \
while (0)
/* Before we start, one word about the strange constants.
They are defined in RFC 1321 as
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
*/
/* Round 1. */
OP(A, B, C, D, 7, 0xd76aa478);
OP(D, A, B, C, 12, 0xe8c7b756);
OP(C, D, A, B, 17, 0x242070db);
OP(B, C, D, A, 22, 0xc1bdceee);
OP(A, B, C, D, 7, 0xf57c0faf);
OP(D, A, B, C, 12, 0x4787c62a);
OP(C, D, A, B, 17, 0xa8304613);
OP(B, C, D, A, 22, 0xfd469501);
OP(A, B, C, D, 7, 0x698098d8);
OP(D, A, B, C, 12, 0x8b44f7af);
OP(C, D, A, B, 17, 0xffff5bb1);
OP(B, C, D, A, 22, 0x895cd7be);
OP(A, B, C, D, 7, 0x6b901122);
OP(D, A, B, C, 12, 0xfd987193);
OP(C, D, A, B, 17, 0xa679438e);
OP(B, C, D, A, 22, 0x49b40821);
#undef OP
#define OP(f, a, b, c, d, k, s, T) \
do \
{ \
a += f (b, c, d) + correct_words[k] + T; \
a = rol(a, s); \
a += b; \
} \
while (0)
/* Round 2. */
OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
OP(FG, D, A, B, C, 6, 9, 0xc040b340);
OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
OP(FG, D, A, B, C, 10, 9, 0x02441453);
OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
/* Round 3. */
OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
OP(FH, D, A, B, C, 8, 11, 0x8771f681);
OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
OP(FH, B, C, D, A, 6, 23, 0x04881d05);
OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
/* Round 4. */
OP(FI, A, B, C, D, 0, 6, 0xf4292244);
OP(FI, D, A, B, C, 7, 10, 0x432aff97);
OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
OP(FI, C, D, A, B, 6, 15, 0xa3014314);
OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
/* Put checksum in context given as argument. */
ctx->A += A;
ctx->B += B;
ctx->C += C;
ctx->D += D;
}
/* The routine updates the message-digest context to
* account for the presence of each of the characters inBuf[0..inLen-1]
* in the message whose digest is being computed.
*/
static void md5_write(MD5_CONTEXT* hd, unsigned char* inbuf, size_t inlen)
{
if (hd->count == 64) { /* flush the buffer */
transform(hd, hd->buf);
hd->count = 0;
hd->nblocks++;
}
if (!inbuf)
return;
if (hd->count) {
for (; inlen && hd->count < 64; inlen--)
hd->buf[hd->count++] = *inbuf++;
md5_write(hd, NULL, 0);
if (!inlen)
return;
}
while (inlen >= 64) {
transform(hd, inbuf);
hd->count = 0;
hd->nblocks++;
inlen -= 64;
inbuf += 64;
}
for (; inlen && hd->count < 64; inlen--)
hd->buf[hd->count++] = *inbuf++;
}
/* The routine final terminates the message-digest computation and
* ends with the desired message digest in mdContext->digest[0...15].
* The handle is prepared for a new MD5 cycle.
* Returns 16 bytes representing the digest.
*/
static void md5_final(MD5_CONTEXT* hd)
{
u32 t, msb, lsb;
unsigned char* p;md5_write(hd, NULL, 0); /* flush */;
t = hd->nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
if ((lsb += hd->count) < t)
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
lsb <<= 3;
msb <<= 3;
msb |= t >> 29;if (hd->count < 56) { /* enough room */
hd->buf[hd->count++] = 0x80; /* pad */
while (hd->count < 56)
hd->buf[hd->count++] = 0; /* pad */
}
else { /* need one extra block */
hd->buf[hd->count++] = 0x80; /* pad character */
while (hd->count < 64)
hd->buf[hd->count++] = 0;
md5_write(hd, NULL, 0); /* flush */;
memset(hd->buf, 0, 56); /* fill next block with zeroes */
}
/* append the 64 bit count */
hd->buf[56] = lsb;
hd->buf[57] = lsb >> 8;
hd->buf[58] = lsb >> 16;
hd->buf[59] = lsb >> 24;
hd->buf[60] = msb;
hd->buf[61] = msb >> 8;
hd->buf[62] = msb >> 16;
hd->buf[63] = msb >> 24;
transform(hd, hd->buf);p = hd->buf;
#ifdef BIG_ENDIAN_HOST
#define X(a) do { *p++ = hd-> a ; *p++ = hd-> a >> 8; \
*p++ = hd-> a >> 16; *p++ = hd-> a >> 24; } while(0)
#else /* little endian */
#define X(a) do { *(u32*)p = hd-> a ; p += 4; } while(0)
#endif
X(A);
X(B);
X(C);
X(D);
#undef X
}
int main(int argc, char** argv)
{
assert(sizeof(u32) == 4);if (argc < 2)
{
fprintf(stderr, "usage: md5sum filenames\n");
exit(1);
}
for (argc--, argv++; argc; argv++, argc--)
{
FILE* fp;
unsigned char buffer[4096];
size_t n;
MD5_CONTEXT ctx;
int i;fp = fopen(*argv, "rb");
if (!fp)
{
fprintf(stderr, "can't open `%s': %s\n", *argv, strerror(errno));
exit(1);
}md5_init(&ctx);
while ((n = fread(buffer, 1, sizeof buffer, fp)))
md5_write(&ctx, buffer, n);if (ferror(fp))
{
fprintf(stderr, "error reading `%s': %s\n", *argv, strerror(errno));
exit(1);
}
md5_final(&ctx);
fclose(fp);for (i = 0; i < 16; i++)
printf("%02x", ctx.buf[i]);
printf(" %s\n", *argv);
}
return 0;
}
/*
Local Variables:
compile-command: "gcc -Wall -o md5sum md5sum.c"
End:
*/
边栏推荐
猜你喜欢

Ali's official Redis development specification

缓存一致性MESI与内存屏障

22年镜头“卷”史,智能手机之战卷进死胡同

【黑马早报】胡军代言悟空理财涉嫌欺诈,疑似涉及390亿元;涪陵榨菜回应榨菜吃出脚指甲; 鸿星尔克再捐1个亿;腾讯控股股价跌回5年前...

05 Doris cluster construction

MySQL's maximum recommended number of rows is 2000w, is it reliable?

酷逼了 Pathetic Dog 第 304 场周赛

RecSys'22|CARCA:交叉注意力感知上下文和属性进行推荐

基于BiGRU和GAN的数据生成方法

The site is not found after the website is filed. You have not bound this domain name or IP to the corresponding site! The configuration file does not take effect!
随机推荐
04 flink cluster construction
金仓数据库KingbaseES安全指南--6.5. LDAP身份验证
02 es cluster construction
DataTable Helper Class for C#
极化微波成像概述2
08 spark 集群搭建
快速抽取resnet_v2_152中间的特征层
程序员架构修炼之道:如何设计“易理解”的系统架构?
关系运算符和if,else语句
金仓数据库 OCCI迁移指南(2. 概述)
RecSys'22|CARCA: Cross-Attention-Aware Context and Attribute Recommendations
不需要写代码,快速批量修改文件夹中图片的格式
数字化采购管理系统开发:精细化采购业务流程管理,赋能企业实现“阳光采购”
开发工具:第五章:使用idea生成实体类
插入排序 优化插入排序
金仓数据库 KingbaseES V8.3 至 V8.6 迁移最佳实践(4. V8.3 到 V8.6 数据库移植实战)
LeaRun.net快速开发动态表单
MySQL's maximum recommended number of rows is 2000w, is it reliable?
11 一发布就发布一系列系列
03 gp cluster construction