关于 MD5 实现中的一行
About one line in an implementation of MD5
中的一行代码感到困惑
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
{
MD5_u32plus saved_lo;
unsigned long used, available;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used)
{
available = 64 - used;
if (size < available)
{
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, available);
data = (const unsigned char *)data + available;
size -= available;
body(ctx, ctx->buffer, 64);
}
if (size >= 64)
{
data = body(ctx, data, size & ~(unsigned long)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
问题行是if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
,好像'size'是字节数,但是'ctx->lo'和'saved_lo'是字节数。为什么把它们加在一起? Github中也有一些类似的代码,也有一些项目使用了这些代码。所以谁能给个解释?
关于“位计数器”的评论可能具有误导性 - ctx->hi
和 ctx->lo
计算字节,就像 size
一样。
您正确地注意到您只是将 size
(字节)添加到 ctx->lo
(然后检查 overflow/propagating 溢出到 ctx->hi
)。溢出检查很简单——lo
作为一个29位的整数,如果adding/masking之后的结果小于原来的值,那么就发生了溢出。
围绕 used
的检查也证明 ctx->lo
和 ctx->hi
是字节计数器 -- body
处理数据 64 字节一次,lo
计数器与0x3F
(即63)进行AND运算。
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
{
MD5_u32plus saved_lo;
unsigned long used, available;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used)
{
available = 64 - used;
if (size < available)
{
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, available);
data = (const unsigned char *)data + available;
size -= available;
body(ctx, ctx->buffer, 64);
}
if (size >= 64)
{
data = body(ctx, data, size & ~(unsigned long)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
问题行是if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
,好像'size'是字节数,但是'ctx->lo'和'saved_lo'是字节数。为什么把它们加在一起? Github中也有一些类似的代码,也有一些项目使用了这些代码。所以谁能给个解释?
关于“位计数器”的评论可能具有误导性 - ctx->hi
和 ctx->lo
计算字节,就像 size
一样。
您正确地注意到您只是将 size
(字节)添加到 ctx->lo
(然后检查 overflow/propagating 溢出到 ctx->hi
)。溢出检查很简单——lo
作为一个29位的整数,如果adding/masking之后的结果小于原来的值,那么就发生了溢出。
围绕 used
的检查也证明 ctx->lo
和 ctx->hi
是字节计数器 -- body
处理数据 64 字节一次,lo
计数器与0x3F
(即63)进行AND运算。