最近看MD5的代码,看到下面一段有疑惑
部分代码
void CMD5Checksum::Update( BYTE* Input, ULONG nInputLen ) { //Compute number of bytes mod 64 UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3F); //Update number of bits if ( ( m_nCount[0] += nInputLen << 3 ) < ( nInputLen << 3) ) //对条件成立的部分有疑惑 { m_nCount[1]++; } m_nCount[1] += (nInputLen >> 29); ……………… // Buffer remaining input memcpy( &m_lpszBuffer[nIndex], &Input[i], nInputLen-i); }
代码功能:Implementation of main MD5 checksum algorithm
其中,m_nCount数组的定义: ULONG m_nCount[2]; //number of bits, modulo 2^64 (lsb first)
用两个32位的数保存不超过64位的明文长度,上诉条件成立的地方,是利用m_nCount[0]数组溢出时,会小于nInputLen,则高位储存一位数据。
要正确的保存数据的长度,只有当m_nCount[0]溢出的时候是mod 2^32 次方时才行。但记忆中int类的数据溢出时会存储一个无规律的大数,那么,是因为nInputLen << 3 语句先让nInputLen移位了,m_nCount[0]操作的对象变成对二进制进行操作,高位就自动溢出达到mod 2^32效果?如何是此原因,当普通的+,-时,即没有后面的 nInputLen << 3移位,数据溢出后数据本身是如何变化的呢?
有符号数值溢出后,会导致最高位的符号位发生变化,也就是0x7FFFFFFF + 1后,会变成-0x7FFFFFFF,
无符号,则会导致0xFFFFFFFF+1=0x100000000 & 0xFFFFFFFF = 0
而移位操作,无论左移还是右移都是补0