• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Problem mit zahlen in Uint8Array

Z

zirzofer

Guest
zwei funktionen, um einen string zu einem uint8array zu konvertieren bzw. umgekehrt:
Code:
	var strToUint8 = function (string) {
		let encodedString, uint8Array;
		encodedString = encodeURIComponent(string).replace(/%([0-9A-F]{2})/g, function (match, p1) {
			return String.fromCharCode("0x" + p1);
		});
		uint8Array = new Uint8Array(encodedString.length);
		Array.prototype.forEach.call(encodedString, function (c, i) {
			uint8Array[i] = c.charCodeAt(0);
		});
		return uint8Array;
	};	
	var uint8ToStr = function (uint8Array) {
		let string, encodedString;
		string = Array.prototype.map.call(uint8Array, function (c) {
			return String.fromCharCode(c);
		}).join("");
		encodedString = string.replace(/(.)/g, function (m, p) {
			let code;
			code = p.charCodeAt(p).toString(16).toUpperCase();
			if (code.length < 2) {
				code = "0" + code;
			}
			return "%" + code;
		});
		return decodeURIComponent(encodedString);
	};
	
	var a = strToUint8("demo #!");
	console.info(uint8ToStr(a));
	
	var b = strToUint8("demo 123");
	console.info(uint8ToStr(b));
Funktioniert soweit auch. Bloss nicht, wenn der String eine Zahl enthält: URIError: malformed URI sequence

was ist falsch, wie mache ich es richtig?
 
das sollte eigentlich niee gehen
Solange p keine Zahl ist, funktioniert das...

@zirzofer: Das ist einfach falsch! Ersetze das durch p.charCodeAt(0) und es funktioniert. Aber warum verwendest du nicht, wie im anderen Thread, TextEncoder? Das liefert doch einen Uint8Array:
Code:
var encoder = new TextEncoder("utf-8");
console.log(encoder.encode("ä"));
 
Solange p keine Zahl ist, funktioniert das...
blöde regel
if it is not a number, it defaults to 0.
dann sollte "1" aber auch funktionieren

Aber warum verwendest du nicht, wie im anderen Thread, TextEncoder? Das liefert doch einen Uint8Array
Code:
console.log(encoder.encode("ä")[0], encoder.encode("ä")[1], "ä".charCodeAt(0), String.fromCharCode(228), String.fromCharCode(228).charCodeAt(0));
 
dann sollte "1" aber auch funktionieren
Äh... warum? p ist genau ein Zeichen lang und 1 würde das zweite Zeichen zurückliefern, das es nicht gibt - also wird's NaN:
Code:
console.log("a".charCodeAt(1))

Code:
console.log(encoder.encode("ä")[0], encoder.encode("ä")[1], "ä".charCodeAt(0), String.fromCharCode(228), String.fromCharCode(228).charCodeAt(0));
K.A. was du mir/uns damit sagen willst.

Wieder: warum?

Bitte - gern geschehen.
 
Äh... warum? p ist genau ein Zeichen lang und 1 würde das zweite Zeichen zurückliefern, das es nicht gibt - also wird's NaN:
Code:
console.log("a".charCodeAt(1))
wiel "1"

K.A. was du mir/uns damit sagen willst.
daß ä in utf8 195, 164 ist und der utf8-codepoint 228 den du mit fromCharCode aus dem 8bit-array ausliest somit in der rückwandlung zu 195, 164 würde.

weil, wie ich schon am anfang schrieb, du komplett mit ISO-8859 encoding arbeiten musst damit das geht.
sprich wenn du wieder zurückwandeln willst musst du den ISO-8859-1 code erzeugen, der identisch zum utf8-codepoint ist, das macht(ob definiert ist noch die frage) charCodeAt wenn du das script ISO-8859 codiert einbindest
 
Das ist String - ja, aber da wird eine automatische Konvertierung durchgeführt. Deswegen interpretiert .charCodeAt() das als 1.

daß ä in utf8 195, 164 ist und der utf8-codepoint 228 den du mit fromCharCode aus dem 8bit-array ausliest somit in der rückwandlung zu 195, 164 würde.
Da darfst du natürlich nicht direkt mit fromCharCode() arbeiten, sondern kannst z.B. den TextDecoder verwenden. Du musst hald sauber das UTF8 wieder in UCS-2 umwandeln.

weil, wie ich schon am anfang schrieb, du komplett mit ISO-8859 encoding arbeiten musst damit das geht.
1. Wo "am anfang" hast du das geschrieben? Du erwähnst das hier gerade zum ersten mal.
2. Warum muss man mit ISO-8859 arbeiten? TextEncoder und TextDecoder funktionieren wunderbar mit UTF-8:
Code:
var str = "mein Teststring: äöüáß^hlk234567ø†»";
var a = (new TextEncoder("utf-8")).encode(str);
console.log(a, (new TextDecoder("utf-8")).decode(a));

wenn du das script ISO-8859 codiert einbindest
Es ist völlig egal, wie dein Skript codiert ist. JS arbeitet immer mit USC-2 und Unicode-Codepoints.
 
Das ist String - ja
und das verhalten damit falsch

aber da wird eine automatische Konvertierung durchgeführt. Deswegen interpretiert .charCodeAt() das als 1.
"a" ist nach number gecastet NaN und NaN ist eine number

Da darfst du natürlich nicht direkt mit fromCharCode() arbeiten, sondern kannst z.B. den TextDecoder verwenden. Du musst hald sauber das UTF8 wieder in UCS-2 umwandeln.
hatten wir doch schon, nicht weiter oben, war der andere thread. wenn ich den TextDecoder nutze um das 8bit-array in utf8 zu wandeln habe ich ungültige kodierungen

1. Wo "am anfang" hast du das geschrieben? Du erwähnst das hier gerade zum ersten mal.
war der andere thread

2. Warum muss man mit ISO-8859 arbeiten? TextEncoder und TextDecoder funktionieren wunderbar mit UTF-8:
lol, ja so rum schon, andersrum nicht und darum geht es ja

Es ist völlig egal, wie dein Skript codiert ist. JS arbeitet immer mit USC-2 und Unicode-Codepoints.
intern arbeitet js mit utf16, habe nichts anderes behauptet
 
wenn ich den TextDecoder nutze um das 8bit-array in utf8 zu wandeln habe ich ungültige kodierungen
Warum sollte ich ein 8bit-Array in utf-8 "wandeln" (was auch immer du damit meinst...) wollen? Utf-8 Ist ist dazu da, dass man Unicode, der mehr als 8-Bit braucht in 8-Bit speichern kann.

lol, ja so rum schon, andersrum nicht und darum geht es ja
??? TextEncoder codiert etwas in einem Encoding - hier UTF-8... das ist genau das, was hier gemacht werden soll - jedenfalls ein Teil davon.

intern arbeitet js mit utf16
Das ist falsch!
ECMA 6th-Edition schrieb:
Each integer value in the sequence usually represents a single 16-
bit unit of UTF-16 text. However, ECMAScript does not place any restrictions or requirements on the values
except that they must be 16-bit unsigned integers.
Das ist USC-2. In UTF-16 könntest du kein High-Surrogate ohne ein Low-Surrogate haben. Das geht in JS wunderbar:
Code:
console.log("\uD800");
 
TextEncoder codiert etwas in einem Encoding - hier UTF-8... das ist genau das, was hier gemacht werden soll - jedenfalls ein Teil davon.
ja, von mir aus. wenn das aber, was hier als UTF-8 codierte bytewurst erzeugt werden soll, aus einer bytewurst entsteht die nicht UTF-8 codiert ist, ist das mit TextEncoder nicht möglich, weil hier UTF-8 nicht passt, sondern nur ein single byte characterset in frage kommt oder ein multibyte character set mit belibigen bytefolgen

das ist (zum großteil jedenfalls) richtig

Code:
console.log("\uD800");
was sagt uns das über die kodierung?

- - - Aktualisiert - - -

Code:
var xxx = '\uD800\uDFFF';
console.log(xxx, xxx.length);

- - - Aktualisiert - - -

Anhang anzeigen xxx.zip
 
ja, von mir aus. wenn das aber, was hier als UTF-8 codierte bytewurst erzeugt werden soll, aus einer bytewurst entsteht die nicht UTF-8 codiert ist, ist das mit TextEncoder nicht möglich, weil hier UTF-8 nicht passt, sondern nur ein single byte characterset in frage kommt oder ein multibyte character set mit belibigen bytefolgen
Diesen Satz verstehe ich nicht...

was sagt uns das über die kodierung?
Ds sagt uns, dass es kein UTF-16 sein kann, da diese Zeichen alleine kein valider UTF-16 String ist. Dein Codestück sagt genau das gleiche. Dass da in der Console nur ein Zeichen ausgegeben wird, liegt daran, dass der Browser versucht, die Ausgbe als UTF-16 zu interpretieren. Aber Browseranzeige und JS sind, wie man dan dem xxx.length schön sieht, zwei verschiedene Sachen.

K.A., was du uns damit sagen willst.
 
Diesen Satz verstehe ich nicht...
siehe letzter punkt

Ds sagt uns, dass es kein UTF-16 sein kann, da diese Zeichen alleine kein valider UTF-16 String ist.
aber auch kein valider ucs string, es ist einfach so definiert, daß jeder müll im string vorkommen kann, auch wenn es kein valides zeichen ist. die prüfung auf validität gültiger utf16 zeichen ist nur bei bestimmten funktionen definiert

Dein Codestück sagt genau das gleiche. Dass da in der Console nur ein Zeichen ausgegeben wird, liegt daran, dass der Browser versucht, die Ausgbe als UTF-16 zu interpretieren. Aber Browseranzeige und JS sind, wie man dan dem xxx.length schön sieht, zwei verschiedene Sachen.
das zeigt genau das was definiert ist, dass ein zeichen für js als ein 16 bit-wert eines utf16 zeichens definiert ist das hast du doch selbst verlinkt
ECMAScript 2015 Language Specification – ECMA-262 6th Edition

der quellcode von mindestens 2 js-engines ist verfügbar, sieh halt nach, was sie verwenden

K.A., was du uns damit sagen willst.
keine ahnung, wie ich das jetzt noch erklären soll, poste doch mal deinen code mit textencoder welcher den buffer
Code:
var buffer = new Uint8Array([25, 235, 161, 121, 221, 61, 132, 15, 161, 17]);
in einen string wandelt und wieder zurück in ein uint8 array
 
Zurück
Oben