Это код Python для создания хэша ответа:
from hashlib import md5
import struct
....
hashed = md5(struct.pack('>II8s', num1, num2, key3)).digest()
В примере num1 и num2 являются числовыми значениями key1 и key2.key3 - фактическая полученная текстовая строка (необработанные байты).
Вызов struct.pack () использует режим с прямым порядком байтов (для числовых значений) и упаковывает их по 4 байта для каждого числа, за которым следует 8-байтовый ключ3строка (байты).
См. документацию для модуля python struct.
Версия C будет выглядеть примерно так:
/* Pack it big-endian */
buf[0] = (num1 & 0xff000000) >> 24;
buf[1] = (num1 & 0xff0000) >> 16;
buf[2] = (num1 & 0xff00) >> 8;
buf[3] = num1 & 0xff;
buf[4] = (num2 & 0xff000000) >> 24;
buf[5] = (num2 & 0xff0000) >> 16;
buf[6] = (num2 & 0xff00) >> 8;
buf[7] = num2 & 0xff;
strncpy(buf+8, headers->key3, 8);
buf[16] = '\0';
md5_buffer(buf, 16, target);
target[16] = '\0';
md5_buffer находится в glibc .
. Для дальнейшего ознакомления вы можете посмотреть на рабочие реализации (откуда взялся приведенный выше код) websockify (отказ от ответственности: я написал websockify).