我目前正在尝试运行可以与 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