至于“复杂的位碰撞”......是的,它很复杂,但如果你写下你的打包字节和索引到它们来自的解包数组中,很容易弄清楚如何构造每个值...
|........|........|........|........|........|
|00000000|11222222|22334444|44445566|66666677|
上述循环重复3次。
char a[24] = {
0x00,0x00, /* ................ */
0x30,0x00, /* ..@@............ */
0x78,0x00, /* .@@@@........... */
0x48,0x00, /* .@..@........... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xFC,0x00, /* @@@@@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0x00,0x00, /* ................ */
0x00,0x00 /* ................ */
};
void pack( char ap[15], const char a[24] )
{
ap[0] = a[0];
ap[1] = a[1] | (a[2] >> 2 );
ap[2] = (a[2] << 6) | (a[3] >> 2 ) | (a[4] >> 4);
ap[3] = (a[4] << 4) | (a[5] >> 4) | (a[6] >> 6);
ap[4] = (a[6] << 2) | (a[7] >> 6);
ap[5] = a[8];
ap[6] = a[9] | (a[10] >> 2 );
ap[7] = (a[10] << 6) | (a[11] >> 2 ) | (a[12] >> 4);
ap[8] = (a[12] << 4) | (a[13] >> 4) | (a[14] >> 6);
ap[9] = (a[14] << 2) | (a[15] >> 6);
ap[10] = a[16];
ap[11] = a[17] | (a[18] >> 2 );
ap[12] = (a[18] << 6) | (a[19] >> 2 ) | (a[20] >> 4);
ap[13] = (a[20] << 4) | (a[21] >> 4) | (a[22] >> 6);
ap[14] = (a[22] << 2) | (a[23] >> 6);
}
如果您愿意,您可以在一个小循环中执行上述操作,以减少犯错的范围......只需从 0 循环到 2,并相应地推进您的数组。你知道,有点像这样(除非你需要正确的指针):
for( int i = 0; i < 3; i++ ) {
ap[0] = a[0];
ap[1] = a[1] | (a[2] >> 2 );
ap[2] = (a[2] << 6) | (a[3] >> 2 ) | (a[4] >> 4);
ap[3] = (a[4] << 4) | (a[5] >> 4) | (a[6] >> 6);
ap[4] = (a[6] << 2) | (a[7] >> 6);
ap += 5;
a += 8;
}
我希望我把所有这些转变都做对了=)