Ограничение PHP hex2bin

Я конвертирую данные, такие как html, css, из текстовой области браузера в шестнадцатеричный формат, чтобы отправить их через ajax на сервер. Это сделано для того, чтобы избежать срабатывания правил брандмауэра modsecurity xss.

На сервере я использую hex2bin PHP для преобразования шестнадцатеричного значения обратно в HTML.

Все работает так, как должно, НО не преобразуются некоторые символы, такие как £, шестнадцатеричный код которых равен a3, PHP hex2bin отображает их как в браузере.

Есть много других подобных шестнадцатеричных кодов hex2bin, которые не конвертируются. Я делаю что-то не так или есть какая-то другая библиотека, которую я могу использовать, чтобы получить полное шестнадцатеричное покрытие?

<head>
  <meta charset = "utf-8">
</head>
//javascript
var str = '£';
var hex = str.charCodeAt(0).toString(16);
alert(hex); // a3
//php
echo hex2bin('a3'); // �
echo hex2bin('24'); // $
echo hex2bin('ae'); // � should be ®

Похоже, вы отображаете неправильную кодировку.

Barmar 11.07.2024 01:03

Используете ли вы ASCII в js и UTF8 в PHP? c2a3 должно быть utf8. Не могли бы вы добавить больше контекста к вопросу.

user3783243 11.07.2024 03:16

смотрите мой вопрос, я добавил код js и php, который использую

Jsp 11.07.2024 08:07

Вы делаете это просто в качестве упражнения или это должно служить какой-то реальной цели? (Просто пытаюсь выяснить, не пытаетесь ли вы заново изобрести здесь какие-то колеса.)

CBroe 11.07.2024 08:15
hex2bin() работает отлично. Вы просто не создаете действительную последовательность байтов UTF-8.
Olivier 11.07.2024 08:26

Я конвертирую html, css и javascript из текстовой области браузера в шестнадцатеричный формат, чтобы отправить его через ajax на сервер и сохранить в базе данных. Это сделано для того, чтобы избежать срабатывания правил брандмауэра modsecurity xss.

Jsp 11.07.2024 08:26

Решение состоит в том, чтобы использовать функцию utf8ToHex(), указанную здесь. utf8ToHex('£') возвращает c2a3, что дает ожидаемый результат при декодировании с помощью hex2bin().

Olivier 11.07.2024 09:06

Для справки: £ — это U+00A3 «ЗНАК ФУТА». a3 — это кодовая точка Юникода, которая по сути представляет собой каталожный номер и отличается от фактической используемой кодировки.

Álvaro González 11.07.2024 09:25
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
8
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

String.prototype.charCodeAt() производит:

целое число от 0 до 65535, представляющее кодовую единицу UTF-16 по данному индексу.

Поскольку ваш HTML-документ объявляет UTF-8, вам необходимо выполнить преобразование между кодировками. Но вам также не хватает информации, когда первый байт равен нулю, поэтому вам нужно сначала дополнить значение:

$utf16 = hex2bin(str_pad('a3', 4,  '0', STR_PAD_LEFT));
echo mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');

Делать это по одному персонажу за раз не получится. Если вам вообще нужна сериализация (т. е. вы не можете использовать необработанный UTF-8 по какой-либо причине), я бы предложил вам использовать другой механизм сериализации, например Base64:

function bytesToBase64(bytes) {
  const binString = Array.from(bytes, (byte) =>
    String.fromCodePoint(byte),
  ).join("");
  return btoa(binString);
}

const message = 'We accept £ and €';
console.info(bytesToBase64(new TextEncoder().encode(message)));

(Код взят из MDN).

echo base64_decode('V2UgYWNjZXB0IMKjIGFuZCDigqw=');
mb_convert_encoding набивка hex2bin решает проблему в этом вопросе. Однако метод bytesToBase64, предложенный Альваро, является лучшим решением для приложения, над которым я работаю. Спасибо за ответ.
Jsp 11.07.2024 21:39

Я опубликовал функцию, полученную на основе этого ответа на этот вопрос stackoverflow.com/questions/78723233/…

Jsp 11.07.2024 22:24

Другие вопросы по теме