Почему js делает неправильный hex?

У меня есть некий:
var hex = "354d413043b4b440e1510b00";
Я делаю из него строку с помощью:
var not_hex = Buffer.from(hex, 'hex').toString('utf8');

и потом снова делаю строку в hex:
var hex_again = Buffer.from(not_hex, 'utf8').toString('hex');

И в итоге получаю другое значение hex: 354d413043efbfbdefbfbd40efbfbd510b00

Так и должно быть что-ли? Или может быть я не так делаю строку из hex?

(если вы будете расшифровывать первый hex, то там должна получиться билибирда, так и должно быть)
  • Вопрос задан
  • 440 просмотров
Решения вопроса 1
dollar
@dollar
Делай добро и бросай его в воду.
В UTF-8 есть правила. Поэтому не всякая бинарная строка является валидной UTF-8-строкой.
spoiler
Вот вам упрощённый пример. Представим, что вы переводите не в UTF-8, а в ASCII, и что главным правилом является нулевой восьмой бит. Пусть изначальная hex-строка будет FA. При переводе в ascii алгоритм видит, что это какая-то ошибка и решает исправить её, заменив на 7A (символ "z"). Далее при переводе в hex вы уже получаете 7A, а не FA, потому что информация о восьмом бите утеряна.

Можете попробовать так. Возможно, это и решит вашу проблему X:
var hex = "354d413043b4b440e1510b00";
console.log(hex);       // 354d413043b4b440e1510b00

var not_hex = (Buffer.from(hex, "hex").toString("binary"))
console.log(not_hex);   // 5MA0C´´@áQ♂

var hex_again = Buffer.from(not_hex, 'binary').toString("hex");
console.log(hex_again); // 354d413043b4b440e1510b00
console.log(hex === hex_again); // true
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@GrayHorse
Это не байты UTF-8 строки.
Можно было и посмотреть на вывод сначала
console.log((Buffer.from(hex, "hex").toString("utf-8")));

5MA0C��@�Q

https://ru.wikipedia.org/wiki/Заменяющий_символ

[...new TextEncoder().encode("5MA0C��@�Q")].map(n => n.toString(16)).join("")
=== 
"354d413043efbfbdefbfbd40efbfbd51"
// true
Ответ написан
Комментировать
@qwazimord
Интроверт
В чем проблема то? Всё совпадает, если правильно делать
var hex = "354d413043b4b440e1510b00";
var not_hex = Buffer.from(hex, 'hex');
var hex_again = Buffer.from(not_hex, 'utf8').toString('hex');

console.log(hex, not_hex)
console.log(hex_again)
// выводит
// 354d413043b4b440e1510b00 <Buffer 35 4d 41 30 43 b4 b4 40 e1 51 0b 00>
// 354d413043b4b440e1510b00

идентично, символ в символ
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы