Ошибки шифрования в Delphi 10.3 при переходе от ANSI к Unicode
С переходом от Delphi 7.1 на Delphi 10.3 разработчики столкнулись с проблемой, связанной с изменением типов строк в среде разработки. В частности, проблема заключается в том, что при работе со строками фиксированного размера string[25] некоторые специальные символы при шифровании и расшифровке обрабатываются некорректно, в отличие от обычных строк string.
Пример кода с использованием string:
var
test, encrypted, decrypted : string;
begin
test := 'XXXXXXXX'; // скрытое сообщение
encrypted := _common.encrypt(test);
decrypted := _common.decrypt(encrypted);
end;
В данном случае все работает корректно, даже при наличии специальных символов.
Пример кода с использованием string[25]:
var
test, decrypted : string;
encrypted : string[25];
begin
test := 'XXXXXXXX'; // скрытое сообщение
encrypted := _common.encrypt(test);
decrypted := _common.decrypt(encrypted);
end;
В этом случае при наличии специальных символов в зашифрованной строке, они могут быть заменены на другие символы, например, на символы вопросительного знака (?).
Решение проблемы:
Проблема заключается в различии обработки строк string (UnicodeString) и string[25] (ShortString). В Delphi 7.1 использовался ANSI-строка, но начиная с Delphi 2009 по умолчанию используется UnicodeString.
Подтвержденный ответ: Для исправления ошибки необходимо изменить типы переменных, которые объявлены как string, на тип AnsiString. Это позволит избежать смешивания разных типов строк.
Альтернативные варианты решения:
Использование AnsiString для переменных, где ранее был тип string, так как AnsiString совместим с ShortString[25] и не будет приводить к потере специальных символов.
Работа с сырыми бинарными данными при шифровании и расшифровании, что позволит избежать проблем, связанных с различными кодировками строк.
Использование массива символов char, который является двухбайтным и может поддерживать двухбайтовые символы Unicode.
Пример использования StrPLCopy для сохранения строки в массив символов:
var
destArray: array[0..24] of Char;
begin
StrPLCopy(destArray, SourceString, 25);
end;
Необходимо обратить внимание, что функция StrPLCopy не возвращает результат, и его следует использовать как процедуру.
Комментарий к альтернативному ответу:
Работа с необработанными данными (например, байтами) является предпочтительной практикой при выполнении операций шифрования и расшифрования, так как это позволяет избежать проблем, связанных с различными кодировками строк и их обработкой в разных системах.
С учетом необходимости поддержки данных, созданных на старых версиях Delphi, рекомендуется использовать AnsiString для переменных, объявленных как строки фиксированного размера, или перейти на работу с сырыми данными, что позволит избежать ошибок при шифровании и расшифровании данных, содержащих специальные символы.
Проблема заключается в ошибках шифрования в Delphi 10.3, вызванных некорректной обработкой специальных символов при переходе от ANSI к Unicode для строк фиксированного размера, что требует изменения типов строк или работы с сырыми данными.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.