строка — PHP: различные кодировки в POST и GET

У меня проблема с разными наборами символов в GET и POST-запросах в PHP. Вот ситуация:

У меня есть норвежская строка. Эта строка, конечно же, может содержать норвежские символы (то есть «Ensjøsvingen»). Если я передаю эту строку с помощью GET-параметра, извлекаю ее и позволяю считать, она сообщает об ошибке 13 [что правильно]. Если я передаю эту строку через POST-параметр, извлекаю ее и позволяю считать, она выдаёт 17 строчек.

Когда я преобразую строку в шестнадцатеричное с использованием printf, это то, что получается:

ПОЛУЧИТЬ:
45 6e 73 6a c3 b8 73 76 69 6e 67 65 6e

СООБЩЕНИЕ:
45 6e 73 6a 26 23 32 34 38 3b 73 76 69 6e 67 65 6e

Очевидно, POST длиннее. Моя идея заключалась в том, что это была кодировка, поэтому я позволил PHP сказать мне, в каких кодировках находятся строки. PHP сообщает, что GET-String была в UTF-8, а POST-String в ASCII (которая является подмножеством UTF-8). ). Преобразование ASCII в UTF-8 с помощью iconv ничего не меняет в strlen.

Проблема в том, что я использую эту строку для генерации SHA1-хэша для последующего использования (ничего критичного, когда нужно избегать коллизий, поэтому SHA1 вполне подойдет), поэтому я не могу использовать функции mb _ * — для получения точно такого же хеша как строка была передана.

Как я могу решить эту проблему?

2

Решение

Я оставляю свой первоначальный ответ ниже, потому что он включает некоторую информацию, которая мне очень помогла в прошлом. Однако после того, как вы отмените вышеприведенные выходные данные, разница между вашими строками в том, что строка из POST кодируется с использованием сущностей HTML. Обе строки эквивалентны, однако вам нужно будет использовать html_entity_decode (укажите UTF-8 в параметре кодирования), чтобы получить нужные вам результаты. Я оставил свой ответ от ранее, потому что прямое сравнение байтов может все еще потерпеть неудачу после этого по причинам, обсужденным ниже.


Когда PHP принимает ввод из браузера, он ничего не делает с кодировкой символов. При этом для параметров GET он пытается отменить их кодирование. В зависимости от того, как браузер кодирует строки UTF-8, многие символы имеют более одной кодировки в UTF-8. Существует одна кодировка для полного символа и даже несколько различных кодировок, которые используют базовый символ и объединяют диакритические знаки или другие метки для получения того же результата. Для языка, поддерживающего Utf-8, это не проблема, поскольку все кодировки для символа должны рассматриваться как равные, однако, поскольку PHP даже не пытается кодировать символы, вы можете просто столкнуться с двумя различными нормализациями одного и того же строка.

Многие проблемы, которые у меня были в этой связи, были решены с помощью нормализатор внутреннего расширения так что я всегда работал с одной нормальной формой или другой, и прямое сравнение байтов (а не сравнение символов с поддержкой UTF-8) давало бы одинаковые результаты. Это важно помнить со всеми строками UTF-8; strlen () и другие строковые функции PHP, отсутствующие в расширении mb_string, не поддерживают многобайтовый режим, если только вы не включите перегрузку, и поэтому при работе с UTF-8 вы получите количество байтов, а не количество символов.

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

1

Другие решения

Других решений пока нет …