这个C函数是如何工作的 #定义BASE32_ONIONLEN 16 #定义基本32_字母“abcdefghijklmnopqrstuvwxyz234567” void base32_onion(char*dst,unsigned char*src){//base32编码哈希 uint8_t字节=0,//dst位置 偏移量=0;//位偏移量 对于(;字节7){ 偏移量-=8; src++; } dst[byte++]=BASE32_字母[(htobe16(*(uint16_t*)src)>>(11偏移量)) &(uint16_t)0x001F]; } dst[字节]='\0'; }
我无法理解以这个C函数是如何工作的 #定义BASE32_ONIONLEN 16 #定义基本32_字母“abcdefghijklmnopqrstuvwxyz234567” void base32_onion(char*dst,unsigned char*src){//base32编码哈希 uint8_t字节=0,//dst位置 偏移量=0;//位偏移量 对于(;字节7){ 偏移量-=8; src++; } dst[byte++]=BASE32_字母[(htobe16(*(uint16_t*)src)>>(11偏移量)) &(uint16_t)0x001F]; } dst[字节]='\0'; },c,C,我无法理解以dst[byte++]开头的部分。我是一名python程序员,我不确定所有类型转换是如何工作的src指向右边的一个字节?和(uint16\u t*)将其转换为指向2字节值的指针?那么,这是使src处的字节成为两个字节值的开始还是结束?那么>(11偏移量)是怎么回事 #define BASE32_ONIONLEN 16 #define BASE32_ALPHABET "abcdefghijklmnopqrstuvwxyz234567" void base32_onion(char *
dst[byte++]
开头的部分。我是一名python程序员,我不确定所有类型转换是如何工作的src
指向右边的一个字节?和(uint16\u t*)
将其转换为指向2字节值的指针?那么,这是使src
处的字节成为两个字节值的开始还是结束?那么>(11偏移量)
是怎么回事
#define BASE32_ONIONLEN 16
#define BASE32_ALPHABET "abcdefghijklmnopqrstuvwxyz234567"
void base32_onion(char *dst, unsigned char *src) { // base32-encode hash
uint8_t byte = 0, // dst location
offset = 0; // bit offset
for(; byte < BASE32_ONIONLEN; offset += 5) {
if(offset > 7) {
offset -= 8;
src++;
}
dst[byte++] = BASE32_ALPHABET[(htobe16(*(uint16_t*)src) >> (11-offset))
& (uint16_t)0x001F];
}
dst[byte] = '\0';
}
将一个值右移n位相当于将该值除以2n。BASE32_字母是'abcdefghijklmnopqrstuvwxyz234567'BASE32_字母是16请在问题中包含该信息,不在注释中——最好是通过显示
BASE32字母表
和BASE32字母表
的声明。它基本上是根据逻辑以混乱的方式从BASE32字母表
创建一个新字符串dst
。以您的第一个案例offset=0
byte=0
为例,遍历逻辑。(您需要从htobe16
)返回,但它会在每次通过时从BASE32\u字母表中选择字母/数字。您真的应该向朋友或导师询问这一点。这不适合SO。*(uint16_t*)src
是UB——它将未对齐的指针作为短指针访问。在某些平台上,这只会导致崩溃。我知道位移位的作用,只是不知道为什么代码会(11偏移量)
,然后只查看t2>(11偏移量)
的前5位。不过,这确实帮助了我,谢谢。这正是base32洋葱哈希算法的本质。我可以花时间对它进行反向工程,但你不付我薪水。希望这将足以激励你去解决剩下的问题。
uint16_t t1, t2, t3;
uint8_t t4, t5, t6;
t1 = *(uint16_t*)src; // Whatever src is pointing to, treat the next
// 16 bits as an unsigned number
// Safer would be memcpy(&t1, src, sizeof(t1));
t2 = htobe(t1); // Guessing this changes the value to have big-endian
// byte order
t3 = t2 >> (11-offset); // Shift t2 to the right by (11-offset) bits
t4 = t3 & (uint16_t)0x001F; // t4 contains the lower 5 bits of t3
t5 = BASE32_ALPHABET[t4]; // t5 gets the t4-th byte of the base32 alphabet
t6 = byte++; // t6 gets the value of byte, byte's value is then
// incremented, so t6 + 1 == byte
dest[t6] = t5; // t5 is assigned to dest[t6]