Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как получить код символа в нужной кодировке? (https://javascript.ru/forum/misc/81953-kak-poluchit-kod-simvola-v-nuzhnojj-kodirovke.html)

Aetae 20.02.2021 04:15

Цитата:

Сообщение от voraa (Сообщение 533922)
Не думаю. Просто нет хорошего, устраивающего всех решения

Но есть готовый механизм, продуманный в своё время умными людьми: ставишь для form атрибут accept-charset и браузер спокойно кодирует текст в input'ах из текущей кодировки в указанную, перед тем как послать форму на сервер. (Символы не влезающие в кодировку он кодирует как html entity.)
Это конечно типа legacy, но пока не deprecated.)

Жаль только никакого хитрого метода заюзать это в коде я лично не придумал.

voraa 20.02.2021 11:39

Цитата:

Сообщение от repulsor
Значит развели over 9000 этих кодовых таблиц, а теперь простым трудягам в ручную писать?

Ну не так их уж и много.
Разрешенные в TextDecoder (кроме iso-2022-cn, iso-2022-cn-ext) тут
https://developer.mozilla.org/en-US/..._API/Encodings

Для простых кодировок (которые не китайско-японские и ограничиваются 256 кодами) можно прикрутить что то типа такого
<script>
class TextEncoderExt {
	constructor (utfLabel="utf-8", options={fatal:false}) {
// options.fatal  - true - выбрасывать исключение при ошибках кодирования.
// options.code - числовой код, который подставляется для несуществующих символов.
// если не указан, несуществующий символ пропускается.

		if (utfLabel.toLowerCase().indexOf('utf')>=0) return new TextEncoder('utf-8', options)
		this.codetable = {};
		this.opt = options;
		const arb = new Uint8Array(256)
		for (let i = 0; i<256; i++) arb[i]=i; 
		const codestr = new TextDecoder(utfLabel).decode(arb);
		for (let i=0; i<256; i++) this.codetable[codestr.codePointAt(i)] = i;
	}
	
	encode (str) {
		const l = str.length;
		const buf = new Uint8Array(l);
		let j = 0;
		for (let i = 0; i<l; i++) {
			let v = this.codetable[str.codePointAt(i)];
			if (v === undefined) {
				if (this.opt?.fatal) throw new Error('EncodeExt error');
				if (typeof this.opt?.code == 'number') v=this.opt.code & 255;
			}
			if (v !== undefined) buf[j++] = v;
		}
		return (j<l)? buf.slice(0,j) : buf;
	}
}

const strin1="Это строка на кирилице. В “win-1251” и обратно …"

const buf1 = new TextEncoderExt('CP1251').encode(strin1)
const strout1= new TextDecoder('CP1251').decode(buf1)

console.log (strin1)
console.log (strout1)

const strin2="Это строка на кирилице. В “CP866” и обратно …"

const buf2 = new TextEncoderExt('866', {code:240}).encode(strin2) // Ё вместо несуществующих символов
const strout2= new TextDecoder('866').decode(buf2)

console.log (strin2)
console.log (strout2)

const strin3="Это строка на кирилице. В “utf-8” и обратно …"

const buf3 = new TextEncoderExt('utf-8').encode(strin3)
const strout3= new TextDecoder('utf-8').decode(buf3)

console.log (strin3)
console.log (strout3)
</script>

repulsor 20.02.2021 11:51

voraa,
кстати, правильно ли я понял, что CP437 нужно только в ручную выписывать?

voraa 20.02.2021 12:02

Цитата:

Сообщение от repulsor
CP437 нужно только в ручную выписывать?

Ну да.
Такой TextDecoder('cp437') не знает.
Слетает с ошибкой.

repulsor 20.02.2021 12:47

voraa,
самое интересное, что 437 это альма-матер этих ibm кодировок, и что ее путают с другими, хотя они уже от нее образовались...


Часовой пояс GMT +3, время: 08:28.