Зашифровать большую строку в Delphi

Я использую этот метод для шифрования небольших строк в течение длительного времени и отлично работаю. когда я пытаюсь передать большую строку (длина> 500), это не работает кто-нибудь может сказать мне, почему?

`function Encrypt(const Text: string): string;
var
  i: Byte;
  Key: Word;
  strTemp: string;
const
  KEY  = 7519;
  KEY1 = 03001;
  KEY2 = 002279;
begin
  Key := KEY;
  SetLength(strTemp, Length(Text));
  Result := '';
  for i := 1 to Length(Text) do
  begin
    strTemp[i] := Char(byte(Text[I]) xor (Key shr 8));
    Result := Result + IntToHex(Byte(strTemp[i]), 2);
    Key := (Byte(strTemp[i]) + KEY) * KEY1 + KEY2 ;
  end;
end;`

я пытался передать большое значение в base64 примерно с 5000 символов, результат после шифрования примерно 250 символов..

я пытаюсь зашифровать текст base64. base64 извлечен из .jpeg

пример:


    var vText: AnsiString;
    vText := 'iVBORw0KGgoAAAANSUhEUgAAB4AAAAQ4CAYAAADo08FDAAAgAElEQVR4XuydUbbjOJIss5bR+19oz' + '1Fla1KpS4kgCcLdI+z9XpBhbgGRfIisnn/+85///PcX/w8DGMAABsoa+Oeff8pmew1WMWelTJWyPPZdt' +'TzP31LVXO8PwS45jz788XLUmMd6+ubRh8oU//0vRwZp/aVnnzvWxU3FnNUyVcpTKcvz6VExzFgtU6U8l' +'bJUHGp/e09U693eO5G/YwADGOhggAFwhy6TEQMYaGegy0FyxZyVMpHF99FTqTcMfsf2';

Результат = 6EA0B289D3DB602BC0EFCC2F2B38A54FF5916CE39FF43E4F7CACFFF7BB372D2E5485038DE606514C0BC943D55B9246C8.

При каком размере строки начинается проблема? Это даст вам подсказку.

rossum 17.11.2022 13:31

Какую версию Delphi вы используете? Начиная с Delphi 2009, тип string перешел с Ansi на Unicode. Это означает, что один символ больше не равен одному байту. Так что ваши byte-касты выглядят очень подозрительно!

Delphi Coder 17.11.2022 13:33

Может быть, логика шифрования приводит к тому, что какой-то символ становится #0, и метод, который вы используете для просмотра зашифрованной строки, перестает выводить там (т. Е. Он видит строку, как если бы она заканчивалась нулем)?

Matthias B 17.11.2022 13:34

@rossum, иногда 128.. иногда 250.. случайно

wh0v1 17.11.2022 13:39

@DelphiCoder, что я могу сделать?

wh0v1 17.11.2022 13:39

@MatthiasB Я пробовал использовать memo, showmessage и базу данных... конечный результат всегда один и тот же, если вы это имели в виду...

wh0v1 17.11.2022 13:39

Отредактируйте свой вопрос: добавьте несколько примеров фактического кода, как вы вызываете свою функцию. Да, с одним таким большим String. Также укажите, какую версию Delphi вы используете. Расскажите нам, что происходит в вашем случае по каждому примеру.

AmigoJack 17.11.2022 13:43

Я использую Делфи 10.4

wh0v1 17.11.2022 13:45

Это не шифрование как таковое, поскольку людям легко его отменить. Алгоритмы шифрования преобразуют массивы байтов в массивы байтов. Они не работают со строками. Преобразуйте вашу строку в байты UTF8. Затем зашифруйте, используя готовые алгоритмы шифрования. Затем закодируйте эти байты, используя base64.

David Heffernan 17.11.2022 13:57

@DavidHeffernan покажи мне пример

wh0v1 17.11.2022 14:01

Если вы передаете значение AnsiString, то почему параметр Encrypt не является AnsiString, to!?

Delphi Coder 17.11.2022 14:10

@DelphiCoder это просто пример... строка или ansi результат тот же...

wh0v1 17.11.2022 14:41

Вы тоже переключили strTemp на AnsiString?

Delphi Coder 17.11.2022 15:27

@DelphiCoder Да. Тот же результат.

wh0v1 17.11.2022 15:48

Существует бесчисленное множество примеров преобразования текста в UTF-8, шифрования массивов байтов (т. е. ваших байтов UTF-8) и преобразования байтов в строки base64. Это тема, которую освещали бесконечно. Почему бы вам не искать себя, а не просить нас сделать еще один пример?

David Heffernan 17.11.2022 16:22

@DavidHeffernan, почему ты не хочешь ни одного из этих примеров? Спасибо. ответ был сделан.. не вами конечно, вы пришли сюда только для чего?

wh0v1 18.11.2022 15:06

Если вы не можете использовать поисковую систему, чтобы найти что-то, то это будет сложно

David Heffernan 18.11.2022 17:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
17
187
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. Ваша программа не может скомпилироваться, как показано в этом примере, из-за
    var
      Key: Word;
    const
      KEY  = 7519;
    
    Вы отметили этот вопрос как Delphi, и поэтому идентификаторы нечувствительны к регистру: KEY не может быть определен, поскольку Key уже существует. Это может быть возможно только в Паскале, хотя. Поэтому, пожалуйста, сравните пример, который вы нам дали, с вашим фактическим кодом.
  2. Ваша переменная цикла недостаточно велика:
    var
      i: Byte;
    begin
      for i := 1 to Length(Text) do
    
    Если Length(Text) равно 304, тогда цикл будет выполнять только 48 итераций, потому что Byte может содержать максимум 256 значений. Если условие конца цикла имеет более высокое значение, чем переменная может когда-либо храниться, максимальное значение переменной вычитается из этого конечного условия. 304 минус 256 равно 48.
  3. Зачем вам нужна временная строка, если вам нужен только один символ? И даже тогда вы все равно относитесь к is как к Byte, так почему бы не использовать это?
    var
      strTemp: string;
    begin
      SetLength(strTemp, Length(Text));
      for i := 1 to Length(Text) do
      begin
        strTemp[i] := Char(...);
        Result := Result + IntToHex(Byte(strTemp[i]), 2);
        Key := (Byte(strTemp[i]) ...)...;
    
    Это можно записать намного чище:
    var
      byteTemp: Byte;
    begin
      for i := 1 to Length(Text) do
      begin
        byteTemp := Byte(Text[I]) xor (Key shr 8);
        Result := Result + IntToHex(byteTemp, 2);
        Key := (byteTemp + KEY0) * KEY1 + KEY2;
    
  4. Никогда не шифруйте текст — вместо этого шифруйте байты. Декларация
    function Encrypt(const Text: string): string;
    
    будет отличаться в зависимости от версии Delphi. Почему бы не сделать это хотя бы AnsiString? Или еще лучше: TBytes или Array of Byte? Имея дело с любым типом String, вы никогда не можете быть уверены, сколько байтов нужно одному символу. Использование String в Delphi 2009 и более поздних версиях использует более 1 байта на символ, поэтому с Byte(String[i]) вы идете по тонкому льду.

Почему бы не использовать шифрование

Ingo 08.01.2023 14:25

@Info Да, именно так - в этом весь смысл моего поста и его пояснений.

AmigoJack 08.01.2023 15:10

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