关于 MD5 实现中的一行

About one line in an implementation of MD5

我对 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->hictx->lo 计算字节,就像 size 一样。

您正确地注意到您只是将 size(字节)添加到 ctx->lo(然后检查 overflow/propagating 溢出到 ctx->hi)。溢出检查很简单——lo作为一个29位的整数,如果adding/masking之后的结果小于原来的值,那么就发生了溢出。

围绕 used 的检查也证明 ctx->loctx->hi 是字节计数器 -- body 处理数据 64 字节一次,lo计数器与0x3F(即63)进行AND运算。