用Javascript解码UTF-8

用Javascript解码UTF-8,javascript,unicode,utf8-decode,xhtml-transitional,Javascript,Unicode,Utf8 Decode,Xhtml Transitional,我在一个传递UTF-8编码字符串的XHTML网页中有Javascript。它需要继续通过UTF-8版本,并对其进行解码。如何解码UTF-8字符串以便显示 <script type="text/javascript"> // <![CDATA[ function updateUser(usernameSent){ var usernameReceived = usernameSent; // Current value: Größe var usern

我在一个传递UTF-8编码字符串的XHTML网页中有Javascript。它需要继续通过UTF-8版本,并对其进行解码。如何解码UTF-8字符串以便显示

<script type="text/javascript">
// <![CDATA[
function updateUser(usernameSent){
    var usernameReceived = usernameSent; // Current value: Größe
    var usernameDecoded = usernameReceived;  // Decode to: Größe
    var html2id = '';
    html2id += 'Encoded: ' + usernameReceived + '<br />Decoded: ' + usernameDecoded;
    document.getElementById('userId').innerHTML = html2id;
}
// ]]>
</script>

// 

回答原始问题:下面是如何在javascript中解码utf-8:

具体来说,

function encode_utf8(s) {
  return unescape(encodeURIComponent(s));
}

function decode_utf8(s) {
  return decodeURIComponent(escape(s));
}
我们已经在生产代码中使用它6年了,它工作得非常完美

但是,请注意,escape()和unescape()已被弃用。

这应该可以:

// http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt

/* utf.js - UTF-8 <=> UTF-16 convertion
 *
 * Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
 * Version: 1.0
 * LastModified: Dec 25 1999
 * This library is free.  You can redistribute it and/or modify it.
 */

function Utf8ArrayToStr(array) {
    var out, i, len, c;
    var char2, char3;

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

    return out;
}
//http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt
/*utf.js-utf-8 utf-16转换
*
*版权所有(C)1999 Masanao Izumo
*版本:1.0
*最后修改日期:1999年12月25日
*这个图书馆是免费的。您可以重新分发和/或修改它。
*/
函数Utf8ArrayToStr(数组){
var out,i,len,c;
var char2,char3;
out=“”;
len=数组长度;
i=0;
而(我>4)
{ 
案例0:案例1:案例2:案例3:案例4:案例5:案例6:案例7:
//0xxxxxxx
out+=String.fromCharCode(c);
打破
案例12:案例13:
//110x xxxx 10x xxxx
char2=数组[i++];

out+=String.fromCharCode(((c&0x1F)我搜索了一个简单的解决方案,这对我来说非常有效:

//input data
view = new Uint8Array(data);

//output string
serialString = ua2text(view);

//convert UTF8 to string
function ua2text(ua) {
    s = "";
    for (var i = 0; i < ua.length; i++) {
        s += String.fromCharCode(ua[i]);
    }
    return s;               
}
//输入数据
视图=新的UINT8阵列(数据);
//输出字符串
serialString=ua2text(视图);
//将UTF8转换为字符串
功能ua2text(ua){
s=“”;
对于(变量i=0;i

我唯一的问题是有时一次只能得到一个字符。这可能是我的arraybuffer源设计的。我正在用它读取android设备上的串行数据。

@albert的解决方案是我认为最接近的解决方案,但它最多只能解析3字节utf-8字符

function utf8ArrayToStr(array) {
  var out, i, len, c;
  var char2, char3;

  out = "";
  len = array.length;
  i = 0;

  // XXX: Invalid bytes are ignored
  while(i < len) {
    c = array[i++];
    if (c >> 7 == 0) {
      // 0xxx xxxx
      out += String.fromCharCode(c);
      continue;
    }

    // Invalid starting byte
    if (c >> 6 == 0x02) {
      continue;
    }

    // #### MULTIBYTE ####
    // How many bytes left for thus character?
    var extraLength = null;
    if (c >> 5 == 0x06) {
      extraLength = 1;
    } else if (c >> 4 == 0x0e) {
      extraLength = 2;
    } else if (c >> 3 == 0x1e) {
      extraLength = 3;
    } else if (c >> 2 == 0x3e) {
      extraLength = 4;
    } else if (c >> 1 == 0x7e) {
      extraLength = 5;
    } else {
      continue;
    }

    // Do we have enough bytes in our data?
    if (i+extraLength > len) {
      var leftovers = array.slice(i-1);

      // If there is an invalid byte in the leftovers we might want to
      // continue from there.
      for (; i < len; i++) if (array[i] >> 6 != 0x02) break;
      if (i != len) continue;

      // All leftover bytes are valid.
      return {result: out, leftovers: leftovers};
    }
    // Remove the UTF-8 prefix from the char (res)
    var mask = (1 << (8 - extraLength - 1)) - 1,
        res = c & mask, nextChar, count;

    for (count = 0; count < extraLength; count++) {
      nextChar = array[i++];

      // Is the char valid multibyte part?
      if (nextChar >> 6 != 0x02) {break;};
      res = (res << 6) | (nextChar & 0x3f);
    }

    if (count != extraLength) {
      i--;
      continue;
    }

    if (res <= 0xffff) {
      out += String.fromCharCode(res);
      continue;
    }

    res -= 0x10000;
    var high = ((res >> 10) & 0x3ff) + 0xd800,
        low = (res & 0x3ff) + 0xdc00;
    out += String.fromCharCode(high, low);
  }

  return {result: out, leftovers: []};
}
函数utf8ArrayToStr(数组){
var out,i,len,c;
var char2,char3;
out=“”;
len=数组长度;
i=0;
//XXX:忽略无效字节
而(我>7==0){
//0xxx xxxx
out+=String.fromCharCode(c);
继续;
}
//起始字节无效
如果(c>>6==0x02){
继续;
}
//多字节####
//这个字符还剩下多少字节?
var extraLength=null;
如果(c>>5==0x06){
超长=1;
}else如果(c>>4==0x0e){
超长=2;
}如果(c>>3==0x1e),则为else{
超长=3;
}else如果(c>>2==0x3e){
超长=4;
}else如果(c>>1==0x7e){
超长=5;
}否则{
继续;
}
//我们的数据中有足够的字节吗?
如果(i+额外长度>长度){
var剩余=数组切片(i-1);
//如果剩余部分中有无效字节,我们可能希望
//从那里继续。
对于(;i>6!=0x02)中断;
如果(i!=len)继续;
//所有剩余字节都有效。
返回{结果:输出,剩余:剩余};
}
//从字符(res)中删除UTF-8前缀
变量掩码=(1>6!=0x02){break;};
res=(res 10)和0x3ff)+0xd800,
低=(res&0x3ff)+0xdc00;
out+=String.fromCharCode(高、低);
}
返回{result:out,剩菜:[]};
}
如果要对字符串进行分块解析,则返回
{result:“parsed string”,剩菜:[末尾的无效字节列表]}

编辑:修复了@unhammer发现的问题。

也许使用就足够了

但在IE中不受支持

var decoder = new TextDecoder('utf-8'),
    decodedMessage;

decodedMessage = decoder.decode(message.data);
处理非UTF8文本 在本例中,我们解码俄语文本“ПППцц,Мц!”,意思是“你好,世界”。在TextDecoder()构造函数中,我们指定了适用于西里尔文脚本的Windows-1251字符编码

让win1251decoder=newtextdecoder('windows-1251');
let bytes=新的Uint8Array([207、240、232、226、229、242、44、32、236、232、240、33]);

console.log(win1251decoder.decode(bytes));//ППццц,ццц!
这是一个处理所有Unicode代码点的解决方案,包括上限(4字节)值,并受所有现代浏览器(IE和其他>5.5)的支持。它使用decodeURIComponent(),但不使用不推荐的转义/unescape函数:

function utf8_to_str(a) {
    for(var i=0, s=''; i<a.length; i++) {
        var h = a[i].toString(16)
        if(h.length < 2) h = '0' + h
        s += '%' + h
    }
    return decodeURIComponent(s)
}
功能utf8\u至\u str(a){
对于(变量i=0,s='';i

要从字符串创建UTF-8,请执行以下操作:

function utf8_from_str(s) {
    for(var i=0, enc = encodeURIComponent(s), a = []; i < enc.length;) {
        if(enc[i] === '%') {
            a.push(parseInt(enc.substr(i+1, 2), 16))
            i += 3
        } else {
            a.push(enc.charCodeAt(i++))
        }
    }
    return a
}
函数utf8\u来自\u str(s){
对于(变量i=0,enc=encodeURIComponent,a=[];i

已在更新@Albert的答案添加表情符号条件上测试并提供

function Utf8ArrayToStr(array) {
    var out, i, len, c;
    var char2, char3, char4;

    out = "";
    len = array.length;
    i = 0;
    while(i < len) {
    c = array[i++];
    switch(c >> 4)
    { 
      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
        // 0xxxxxxx
        out += String.fromCharCode(c);
        break;
      case 12: case 13:
        // 110x xxxx   10xx xxxx
        char2 = array[i++];
        out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
        break;
      case 14:
        // 1110 xxxx  10xx xxxx  10xx xxxx
        char2 = array[i++];
        char3 = array[i++];
        out += String.fromCharCode(((c & 0x0F) << 12) |
                       ((char2 & 0x3F) << 6) |
                       ((char3 & 0x3F) << 0));
        break;
     case 15:
        // 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
        char2 = array[i++];
        char3 = array[i++];
        char4 = array[i++];
        out += String.fromCodePoint(((c & 0x07) << 18) | ((char2 & 0x3F) << 12) | ((char3 & 0x3F) << 6) | (char4 & 0x3F));

        break;
    }

    return out;
}
函数Utf8ArrayToStr(数组){
var out,i,len,c;
变量char2、char3、char4;
out=“”;
len=数组长度;
i=0;
而(我>4)
{ 
案例0:案例1:案例2:案例3:案例4:案例5:案例6:案例7:
//0xxxxxxx
out+=String.fromCharCode(c);
打破
案例12:案例13:
//110x xxxx 10x xxxx
char2=数组[i++];

out+=String.fromCharCode(((c&0x1F)我认为最简单的方法是使用内置的js函数decodeURI()/encodeURI()


//字符串到Utf8 ByteBuffer

function strToUTF8(str){
  return Uint8Array.from(encodeURIComponent(str).replace(/%(..)/g,(m,v)=>{return String.fromCodePoint(parseInt(v,16))}), c=>c.codePointAt(0))
}
//Utf8字节数组到字符串

function UTF8toStr(ba){
  return decodeURIComponent(ba.reduce((p,c)=>{return p+'%'+c.toString(16),''}))
}
使用我的1.6KB,您可以

ToString(FromUTF8(Array.from(usernameReceived)))

这是我在一次比UTF-8编码/解码更具体的谷歌搜索后发现的。因此,对于那些正在寻找在编码之间转换的转换库的人来说,这是你的选择

从回购自述文件粘贴

支持编码规范中的所有编码:

utf-8 ibm866 iso-8859-2 iso-8859-3 iso-8859-4 iso-8859-5 iso-8859-6 iso-8859-7 iso-8859-8 iso-8
ToString(FromUTF8(Array.from(usernameReceived)))
var uint8array = new TextEncoder().encode(str);
var str = new TextDecoder(encoding).decode(uint8array);
    import {encode, decode} from "fastestsmallesttextencoderdecoder";
    // takes in USVString and returns a Uint8Array object
    const encoded = new TextEncoder().encode('€')
    console.log(encoded);

    // takes in an ArrayBuffer or an ArrayBufferView and returns a DOMString
    const decoded = new TextDecoder().decode(encoded);
    console.log(decoded);