linux ascii到utf-16(然后是sha1和base64)编码

时间:2012-03-13 15:50:32

标签: c++ c linux

我们有一个通信协议,要求我们对Base64编码UTF-16编码密码的SHA1哈希值。我们已经获得了Java,javascript和visual basic示例,但是我们在Linux(redhat)下运行

提供的测试字符串:TESTED@8691
最终输出:rBbBKqbJodT5awZal/CSCYF/sFo=

我试过了

iconv_t conv = iconv_open("UTF-16LE","ASCII"); // open succeeds
char *from_string=strdup("TESTED@8691");
size_t from_length=strlen(from_string);
size_t to_length=from_length*3;
size_t original_to_length=to_length;

char *to_string=(char*)calloc(1,to_length);
int convert_return=iconv(conv,&from_string,&from_length,&to_string,&to_length);
// convert_return is 0 indicating success, to_length is 11, from_length is 0

在to_string上运行sha1和base64编码,长度为22
结果输出:GCXe7HMDoq/NRqo1WWYJDDYZzP0=

如果我循环访问to_string,我得到:

for (int i=0; i<original_to_length-to_length; ++i) {
   printf("to_string %d = %x",i,to_string[i]);  
}

output:
to_string 0 = 0
to_string 1 = 0
to_string 2 = 0
to_string 3 = 0
to_string 4 = 0
to_string 5 = 0
to_string 6 = 0
to_string 7 = 0
to_string 8 = 0
to_string 9 = 0
to_string 10 = 0
to_string 11 = 0
to_string 12 = 0
to_string 13 = 0
to_string 14 = 21
to_string 15 = 0
to_string 16 = 0
to_string 17 = 0
to_string 18 = 4
to_string 19 = 7e
to_string 20 = 13
to_string 21 = e

以下是javascript转换:

function str2rstr_utf16le(input)
{
   var output = "";
   for(var i = 0; i < input.length; i++)
    output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
                              (input.charCodeAt(i) >>> 8) & 0xFF);

   return output;
}

我缺少什么?
谢谢

2 个答案:

答案 0 :(得分:2)

我使用shell脚本进行了检查,看来您给出的结果确实是正确的,只要您假设UTF-16为UTF-16LE(Little Endian):

$ echo -e $(echo -n 'TESTED@8691' | iconv -f utf-8 -t utf-16le | sha1sum - | egrep -o '[0-9a-f]+' | sed -r 's/(..)/\\x\1/g') | tr -d '\n'  | base64
rBbBKqbJodT5awZal/CSCYF/sFo=

对于Big-Endian,我得到YrAwH9v3d88gjvsg0Hypu2Cfjc8=这不是你的结果,所以我认为字节顺序不是问题所在。

man page for iconv(3)州:

The  iconv  function converts one multibyte character at a
time, and for  each  character  conversion  it  increments
*inbuf  and  decrements *inbytesleft by the number of con­
verted input bytes, it increments *outbuf  and  decrements
*outbytesleft by the number of converted output bytes, and
it updates the conversion state contained in cd.

这表明iconv修改了您的目标缓冲区指针(to_string) - 这就是您传递&to_string而不是to_string本身的原因。因此,您可能需要在to_string之后和之后的操作(SHA1和BASE64)之前减去从iconv处理的字节数。

答案 1 :(得分:0)

来自维基百科。

  

对于互联网协议,IANA已批准“UTF-16”,“UTF-16BE”和   “UTF-16LE”作为这些编码的名称。 (这些名字都是个案   不敏感。)别名UTF_16或UTF16在某些方面可能有意义   编程语言或软件应用程序,但它们不是   Internet协议中的标准名称。

我认为UTF-16BEUTF-16LE是Big Endian和Little Endian编码,具有代表性。您使用UTF-16但输入数据的“错误”字节序非常好。

编辑:快速搜索确认了我的怀疑UTF-16LE is "UTF-16, Little Endian"。输入数据是Big Endian的几率非常高。如果是这种情况,所有“高端”UTF-16字节都被置于“低端”字节位置(反之亦然)。

查看您是否使用“UTF-16BE”获得预期结果。