Linux ASCII для UTF-16 (затем Sha1 и Base64) кодировать - PullRequest
0 голосов
/ 13 марта 2012

У нас есть протокол связи, который требует, чтобы Base64 закодировал SHA1-хэш пароля в кодировке UTF-16.Нам были предоставлены Java, javascript и основные визуальные примеры, однако мы работаем под 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

выполнить кодирование sha1 и base64 для to_string с длиной 22 * ​​1011 * результирующий вывод: 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 ]

2 голосов
/ 13 марта 2012

Я проверил, используя сценарий оболочки, и кажется, что результат, который вы дали, действительно верный, если вы предполагаете, что 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=

Для больших-Индиан, я получаю YrAwH9v3d88gjvsg0Hypu2Cfjc8=, который не является твоим результатом, поэтому я думаю, что здесь не проблема порядка байтов.

Страница руководства для 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 после iconv и перед дальнейшими операциями (SHA1 и BASE64).

0 голосов
/ 13 марта 2012

Из Википедии.

Для интернет-протоколов IANA одобрило UTF-16, UTF-16BE и «UTF-16LE» как названия для этих кодировок. (Имена регистр нечувствителен.) Псевдонимы UTF_16 или UTF16 могут быть значимыми в некоторых языки программирования или программные приложения, но они не являются стандартные имена в интернет-протоколах.

Я полагаю, что UTF-16BE и UTF-16LE являются кодировками Big Endian и Little Endian, как говорится. Скорее всего, вы используете UTF-16, но с «неправильным» порядком байтов для ваших входных данных.

Редактировать: Быстрый поиск подтверждает мои подозрения UTF-16LE - это "UTF-16, Little Endian" . Отличная вероятность того, что ваши входные данные были Big Endian. В этом случае все ваши байты UTF-16 «верхнего уровня» помещаются в позицию байта «нижнего уровня» (и наоборот).

Посмотрите, получите ли вы ожидаемый результат с "UTF-16BE".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...