- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我目前正在尝试运行一个可以与 WebSocket 通信的 C++ 服务器。 HandShake 由几个步骤组成,我在最后一个步骤中没有成功。
第一步是生成一个 SHA1 编码的字符串,我成功地获得了正确的十六进制字符串。 (例如 http://en.wikipedia.org/wiki/WebSocket 和 https://www.rfc-editor.org/rfc/rfc6455 )。
两种情况下我的输出都与文档中所述相同:
Wikipedia: 1d 29 ab 73 4b 0c 95 85 24 00 69 a6 e4 e3 e9 1b 61 da 19 69
My Server: 1d 29 ab 73 4b 0c 95 85 24 00 69 a6 e4 e3 e9 1b 61 da 19 69
IETF Docu: b3 7a 4f 2c c0 62 4f 16 90 f6 46 06 cf 38 59 45 b2 be c4 ea
My Server: b3 7a 4f 2c c0 62 4f 16 90 f6 46 06 cf 38 59 45 b2 be c4 ea
原来如此。当我现在进行 Base64 编码时,我得到以下结果:
Wikipedia: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
My Server: MWQyOWFiNzM0YjBjOTU4NTI0MDA2OWE2ZTRlM2U5MWI2MWRhMTk2OQ==
IETF Docu: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
My Server: YjM3YTRmMmNjMDYyNGYxNjkwZjY0NjA2Y2YzODU5NDViMmJlYzRlYQ==
而这完全不同。我确认我的 Base64 算法适用于某些在线转换器,它们都产生了我的服务器所做的输出。所以问题是输入格式。我在一个 javascript 论坛中找到了一个论坛条目,其中一个人遇到了同样的问题,答案是,我们应该传递 20 个字符的二进制表示,而不是传递 40 个字符的十六进制字符串。
我知道 openssl SHA1 返回二进制表示,但由于某些原因我不能使用该库。我使用的 SHA1 库将编码输出放在一个 int 数组中。输出如下所示(IETF 示例):
result[0] = 3011137324
result[1] = 3227668246
result[2] = 2432058886
result[3] = 3476576581
result[4] = 2998846698
我像这样将它转换为十六进制:
std::ostringstream oss;
oss << std::setfill('0');
for (int i = 0; i < 5; ++i) {
oss << std::setw(8) << std::hex << result[i];
}
现在是大问题。如何将十六进制字符串转换为二进制字符串?
提前致谢。马库斯
编辑
如果有人对代码感兴趣: https://github.com/MarkusPfundstein/C---Websocket-Server
最佳答案
我在 c 中测试 websocket,发现字节顺序错误。调整顺序(反向)解决了我的 base64 编码问题,导致正确接受的 key 字符串:
unsigned char byteResult [20];
for(i = 0; i < 5; i++) {
byteResult[(i * 4) + 3] = sha.result[i] & 0x000000ff;
byteResult[(i * 4) + 2] = (sha.result[i] & 0x0000ff00) >> 8;
byteResult[(i * 4) + 1] = (sha.result[i] & 0x00ff0000) >> 16;
byteResult[(i * 4) + 0] = (sha.result[i] & 0xff000000) >> 24;
}
关于Sha1 的 C++ Base64 - WebSocket 握手,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10572057/
我是一名优秀的程序员,十分优秀!