От UTF-8 до UTF-16LE Javascript

#javascript #encoding #utf-8 #utf-16

#javascript #кодирование #utf-8 #utf-16

Вопрос:

Мне нужно преобразовать строку utf-8 в utf-16LE в javascript, например, с помощью функции iconv() php.

Ie:

 iconv("UTF-8", "UTF-16LE", $string);
  

Вывод должен быть таким:

49 00 6e 00 64 00 65 00 78 00

Я нашел эту функцию для декодирования UTF-16LE, и она работает нормально, но я не знаю, как сделать то же самое для кодирования.

 function decodeUTF16LE( binaryStr ) {
    var cp = [];
    for( var i = 0; i < binaryStr.length; i =2) {
        cp.push( 
             binaryStr.charCodeAt(i) |
            ( binaryStr.charCodeAt(i 1) << 8 )
        );
    }

    return String.fromCharCode.apply( String, cp );
}
  

Вывод заключается в создании двоичного файла, который можно загрузить.

Код:

 function download(filename, text) {
    var a = window.document.createElement('a');

    var byteArray = new Uint8Array(text.length);
    for (var i = 0; i < text.length; i  ) {
        byteArray[i] = text.charCodeAt(i) amp; 0xff;
    }
    a.href = window.URL.createObjectURL(new Blob([byteArray.buffer], {'type': 'application/type'}));

    a.download = filename;

    // Append anchor to body.
    document.body.appendChild(a);
    a.click();

    // Remove anchor from body
    document.body.removeChild(a);
}
  

Комментарии:

1. Почему вы не позволяете пользователю загружать файл UTF8? Есть ли в файле что-то еще, кроме текста из вашей строки?

2. Поскольку это специальный файл для исполняемого файла, если специальные символы, такие как корейский, не конвертированы, exe не сможет проанализировать файл. Да, есть много числовых значений (преобразованных с помощью функции: pack() ).

Ответ №1:

Это должно сделать это:

 var byteArray = new Uint8Array(text.length * 2);
for (var i = 0; i < text.length; i  ) {
    byteArray[i*2] = text.charCodeAt(i) // amp; 0xff;
    byteArray[i*2 1] = text.charCodeAt(i) >> 8 // amp; 0xff;
}
  

Это обратная ваша decodeUTF16LE функция. Обратите внимание, что ни один из них не работает с кодовыми точками за пределами BMP.

Ответ №2:

Большое спасибо, Берги, это отлично работает, сочетаясь со стандартной функцией кодирования от utf8 до utf16:

 function encodeUTF16LE(str) {
    var out, i, len, c;
    var char2, char3;

    out = "";
    len = str.length;
    i = 0;
    while(i < len) {
        c = str.charCodeAt(i  );
        switch(c >> 4)
        { 
          case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
            // 0xxxxxxx
            out  = str.charAt(i-1);
            break;
          case 12: case 13:
            // 110x xxxx   10xx xxxx
            char2 = str.charCodeAt(i  );
            out  = String.fromCharCode(((c amp; 0x1F) << 6) | (char2 amp; 0x3F));
            out  = str.charAt(i-1);
            break;
          case 14:
            // 1110 xxxx  10xx xxxx  10xx xxxx
            char2 = str.charCodeAt(i  );
            char3 = str.charCodeAt(i  );
            out  = String.fromCharCode(((c amp; 0x0F) << 12) | ((char2 amp; 0x3F) << 6) | ((char3 amp; 0x3F) << 0));
            break;
        }
    }

    var byteArray = new Uint8Array(out.length * 2);
    for (var i = 0; i < out.length; i  ) {
        byteArray[i*2] = out.charCodeAt(i); // amp; 0xff;
        byteArray[i*2 1] = out.charCodeAt(i) >> 8; // amp; 0xff;
    }

    return String.fromCharCode.apply( String, byteArray );
}