webentwicklung-frage-antwort-db.com.de

Dekodieren Sie UTF-8 mit Javascript

Ich habe Javascript in einer XHTML-Webseite, die UTF-8-kodierte Zeichenfolgen übergibt. Es muss weiterhin die UTF-8-Version durchlaufen und dekodiert werden. Wie kann eine UTF-8-Zeichenfolge für die Anzeige dekodiert werden?

<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>
36
Jarrett Mattson

Um die ursprüngliche Frage zu beantworten: So decodieren Sie utf-8 in Javascript:

http://ecmanaut.blogspot.ca/2006/07/encoding-decoding-utf8-in-javascript.html

Speziell,

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

function decode_utf8(s) {
  return decodeURIComponent(escape(s));
}

Ich habe dies nur in meinem Code verwendet, und es funktioniert perfekt.

97
CpnCrunch

Das sollte funktionieren:

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

/* utf.js - UTF-8 <=> UTF-16 convertion
 *
 * Copyright (C) 1999 Masanao Izumo <[email protected]>
 * 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;
}

Schauen Sie sich die JSFiddle Demo an.

Siehe auch die verwandten Fragen: hier und hier

17
Albert

Die Lösung von @ albert war meiner Meinung nach am nächsten, aber es können nur bis zu 3 Byte utf-8-Zeichen analysiert werden

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: []};
}

Dies gibt {result: "parsed string", leftovers: [list of invalid bytes at the end]} zurück, falls Sie die Zeichenfolge in Blöcken analysieren.

BEARBEITEN: das Problem behoben, das @unhammer gefunden hat.

6
fakedrake

Update @ Alberts Antwort, die Bedingung für Emoji hinzufügt. 

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;
}
5
lauthu

Die folgende Lösung behandelt alle Unicode-Codepunkte, einschließlich der oberen 4 Byte-Werte, und wird von allen modernen Browsern (IE und andere> 5.5) unterstützt. Es verwendet decodeURIComponent (), jedoch NICHT die veralteten Escape/Unescape-Funktionen:

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)
}

Getestet und verfügbar auf GitHub

So erstellen Sie UTF-8 aus einem String:

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
}

Getestet und verfügbar auf GitHub

5
Matthew Voss

Vielleicht reicht es aus, den textDecoder zu verwenden.

Wird jedoch nicht in allen Browsern unterstützt. Es kann jedoch ausreichend sein, wenn Sie crosswalk oder einen anderen Anwendungsfall verwenden, bei dem Sie wissen, welcher Browser verwendet wird.

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

decodedMessage = decoder.decode(message.data);
2
Jonathan

// String an 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 ByteArray in eine Zeichenfolge

function UTF8toStr(ba){
  return decodeURIComponent(ba.reduce((p,c)=>{return p+'%'+c.toString(16),''}))
}
2
user9642681

Ich denke, der einfachste Weg wäre, die eingebauten js-Funktionen decodeURI ()/encodeURI () zu verwenden.

function (usernameSent) {
  var usernameEncoded = usernameSent; // Current value: utf8
  var usernameDecoded = decodeURI(usernameReceived);  // Decoded
  // do stuff
}
1
Kasparow

Mit meiner 1.6KB Bibliothek können Sie das tun

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

Dies ist, was ich nach einer spezifischeren Google-Suche gefunden habe, als nur UTF-8 encode/decode. Für diejenigen, die eine konvertierende Bibliothek suchen, um zwischen Kodierungen zu konvertieren, sind Sie hier.

https://github.com/inexorabletash/text-encoding

var uint8array = new TextEncoder().encode(str);
var str = new TextDecoder(encoding).decode(uint8array);

Aus Repo-Readme einfügen

Alle Kodierungen aus der Kodierungsspezifikation werden unterstützt:

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-8859-8-i ISO-8859- 10 ISO-8859-13 ISO-8859-14 ISO-8859-15 ISO-8859-16 Koi8-r Koi8-D Macintosh Windows-874 Windows-1250 Windows-1251 Windows-1252 Windows-1253 Windows-1254 Windows-1255 Fenster -1256 windows-1257 windows-1258 x-mac-cyrillic gb18030 hz-gb-2312 big5 euc-jp iso-2022-jp shift_jis

(Einige Kodierungen werden möglicherweise unter anderen Namen unterstützt, z. B. ASCII, ISO-8859-1 usw. Weitere Informationen zu jeder Kodierung finden Sie unter Kodierung.)

0
Olle Tiinus