我正试图将一个十六进制字符串转换成一个长的位序列。这是Cryptopals挑战(将十六进制转换为base64)中挑战1的一部分。
我的想法是将字符串中的每两个字符转换为其数值的一个字符(同时将第一个字符与16相乘),因为| hex |=4,| char |=8。
然后,每次屏蔽前6位并将其转换为base64。
问题是,在前6位之后,我需要将所有数组左移6次——显然——我不知道该怎么做。
那么,首先,它们是否有更好的方法将十六进制字符串表示为位序列?
我怎样才能把所有的数组左移?我在这里看到了处理移动每个元素并复制它们的解决方案-这是最简单的方法吗?
这就是我目前所做的-我添加了一些额外的步骤来澄清:
int main(int argc, char * argv[]) {
int elm = strlen(argv[1]) / 2;
char *hashBits = malloc(sizeof(char) * elm);
char a,b,c;
for (int i = 0; i < elm; ++i) {
a = charToBinary(argv[1][i*2]); // Convert the char to its numeric value
b = charToBinary(argv[1][i*2+1]);
c = transformToChar(a,b); // multiply the first with 16 and adds the second one
hashBits[i] = c;
}
char base64Bits = 63 << 2;
int elm64 = elm * 2 * 4 / 6;
char *hashIn64Base = malloc(sizeof(char) * elm64);
for (int j = 0; j < elm64; ++j) {
hashIn64Base[j] = toBaseSixtyFour((hashBits[0] & base64Bits) >> 2);
hashBits = hashBits << 6; //***This is obviously wrong but - how to do it?***//
}
for (int k = 0; k < elm64; ++k) {
printf("%s", &hashIn64Base[k]);
}
}
最佳答案
你读十六进制字符串的方式看起来应该有用。您不会显示charToBinary
和transformToChar
,但是根据函数调用旁边的注释,您应该以字符串将表示的字节数组结束,因此方法(假设它实现正确)是正确的。
至于创建base64字符串,对于每个base64字符将整个数组移动6位是错误的方法。
利用8*3==6*4这个事实。一次取3个字节并将其转换为4个base64字符。您可以通过循环遍历获取当前元素的数组以及执行转换的下两个元素,并在每次迭代中将索引增加3。
您需要检查字节数是否是3的倍数。如果没有,那么最后一个循环迭代将只需要处理1或2个字节。
当发生这种情况时,任何与任何源字节无关的额外base64字符都被设置为=
,并且对某些内容进行编码的字符中的任何额外位都用0填充。
例如,给定以下两个字节:
00000000 11111111
将其分成6位组,如下所示:
000000 001111 111100
请注意,最后一组在末尾有额外的0。因此,最终将得到3个base64字符加上1个
=
。给定一个字节:
11111111
它分为:
111111 110000
所以您将有2个base64字符加上2个
=
。解码时,在末尾有1
=
表示您有2个额外的,有2=
表示您有1个额外的。关于c - 如何表示C中的长位序列?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49698049/