Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > XOR-шифрование


Автор: mr.Anderson 29.5.2006, 16:11
У меня небольшая проблема с этим шифрованием... Оказалось, он не шифрует символ переноса строки. И, значит, как мне кажется, не шифрует и символ табуляции. Это исправляемо? 

Автор: Сый 29.5.2006, 16:37
Странный вопрос. Что передаёшь функции/задаче, то и шифруется (если она, конечно, нормально реализована). 

Автор: maxim1000 29.5.2006, 16:39
xor-шифрование, как и большинство известных мне алгоритмов шифрования не имеет дела с текстом
они имеют дело только с последовательность чисел
поэтому алгоритму, обычно по барабану семантическая нагрузка символа
в более сложные алгоритмы встраивается учёт вероятностей появления того или иного символа, что позволяет затруднить статистические методы взлома
в ещё более сложных алгоритмах могут использоваться какие-нибудь более глубокие данные о символах
но xor - явно не тот случай
тут, ИМХО, проблема находится где-то между приёмом текста от пользователя и отправкой массива байт в алгоритм шифрования... 

Автор: mr.Anderson 29.5.2006, 17:37
хм... сама функция шифровки описана так:
Код

AnsiString XOR_Crypt(AnsiString InStr, AnsiString Key)
{
 AnsiString out="";

 for (int x=1;x<InStr.Length()+1;x++)
  out += (char)(InStr[x] ^ Key[x%Key.Length()+1]);

 return out;
}

А вызывается она вот таким макаром:
Код

Form1->Rezults->Text=XOR_Crypt(Form1->Temp->Text, Form2->XORCryptKey->Text);

Где Rezults - компонент класса TMemo, XOR_Crypt() - собственно функция шифровки, Temp - еще компонент класса TMemo, XORCryptkey - компонент TEdit, в который вводится ключ для расшифровки. 

Автор: mr.Anderson 29.5.2006, 18:36
Да елки! Неужто никто в жизнь не шифровал этим алгоритмом символы переноса строки! 

Автор: maxim1000 29.5.2006, 18:58
1. как проявляется "нешифрование" символов переноса строки
2. неплохо было бы посмотреть шифруемую строку, как последовательность кодов её символов 

Автор: mr.Anderson 29.5.2006, 19:05
секунду.... не понял... сейчас снова попробовал закодировать-расшифровать, почему-то получилось... правда, я там код слегка менял... мда. Ладно, прошу извинить за беспокойство, проблема решилась как-то сама собой...

Добавлено @ 19:16 
Нет, не решилась! Протестировал еще раз, пожестче. Оказалось, что символы переноса строки шифруются нормально! Не шифруется цифра 1 ! Вот что! То есть, я пробовал зашифровать вот такое:
Цитата

0987654321234

В итоге в файле получал кракозябры, как и надо. Расшифровываю, на выходе получаю следующее:
Цитата

098765432

Т.е. символы при шифровке урезаются до единицы. Почему так? То есть проблемой является только единица! 

Автор: sergejzr 29.5.2006, 19:59
У тебя там скорее всего трабла с '\0' тобишь с символом конца строки. Потому что ты работаешь с AnsiString и оператором '+'.
Перепиши функции на char*. 

Автор: mr.Anderson 30.5.2006, 18:44
Эммм.... не получилось... Переписал вот так:
Код

char XOR_Crypt(char *InStr, AnsiString Key)
{
 for (int x=1;x<InStr.Length()+1;x++)
  static char out[] += static_cast<char>((InStr[x] ^ Key[x%Key.Length()+1]));

 return out;
}


Может, где и наврал, но суть не в этом. В функцию, как я писал выше, передается два аргумента типа AnsiString, который нельзя преобразовать в char, как говорит компилер... 

Автор: maxim1000 30.5.2006, 19:35
Цитата(sim7 @  30.5.2006,  17:44 Найти цитируемый пост)
char XOR_Crypt(char *InStr, AnsiString Key)
{
 for (int x=1;x<InStr.Length()+1;x++)


не пойдёт... даже не скомпилируется...
нужно передавать длину строки

P.S.
Модератор: 
судя по всему, проблема не с алгоритмом, так что лучше перемещу это в Delphi... 

Автор: mr.Anderson 30.5.2006, 19:44
P.S. А вот в Delphi этому точно нечего делать. Мы вроде тут С++ разбираем. И, соответственно, Borland C++ Builder, а не Delphi/Kylix.

Не могу понять, как написать функцию... Похоже, придется смириться с ошибкой с единицей. 

Автор: Artemon 30.5.2006, 19:54
У меня была такая проблема с шифрованием методом XOR, решил я ёё следующим способом - перед шифровкой символы '\0' заменял на '\r\m'(или что-то похожее) и все заработало как часы. 

Автор: maxim1000 30.5.2006, 21:18
Цитата(sim7 @  30.5.2006,  18:44 Найти цитируемый пост)
А вот в Delphi этому точно нечего делать

на автомате написал Delphi
зато перенёс правильно smile 

Автор: Partizan 30.5.2006, 23:45
Вот код xor шифрования, который я использовал для шифрования паролей пользователей многопользовательской игры в морской бой, защиты никакой канеш, но от "дурака" вполне приемлемо)))
работает без накладок) 
Код

AnsiString __fastcall TAutorizeForm::Encoding(AnsiString str)
{AnsiString out,pass="!";
for (int x=1;x<str.Length()+1;x++)
        {
        out += (char)(str[x] ^ pass[x%pass.Length()+1]);
        }
return out;

}
 

Автор: Romikgy 31.5.2006, 08:55
Мож уже и не надо , но
Код

AnsiString XOR_Crypt(AnsiString InStr, AnsiString Key)
{ 
AnsiString out=InStr;
char *cho;
cho=new char[InStr.Length()];
strcpy(chp,InStr.c_str());
//////////////////////////
 for (int x=0;x<InStr.Length()-1;x++) 
 cho[x]= (cho[x] ^ Key[x%Key.Length()]);
//////////////////////////
out=AnsiString(cho);
delete(cho);
 return out;
}
 

Автор: takedo 31.5.2006, 09:35
Romikgy, 
Код

AnsiString XOR_Crypt(AnsiString InStr, AnsiString Key)
{
 AnsiString out="";

 for (int x=1;x<InStr.Length()+1;x++)
  out += (char)(InStr[x] ^ Key[x%Key.Length()+1]);

 return out;
}

ничем по сути не отличается от 

Код

AnsiString XOR_Crypt(AnsiString InStr, AnsiString Key)
{ 
AnsiString out=InStr;
char *cho;
cho=new char[InStr.Length()];
strcpy(chp,InStr.c_str());
//////////////////////////
 for (int x=0;x<InStr.Length()-1;x++) 
 cho[x]= (cho[x] ^ Key[x%Key.Length()]);
//////////////////////////
out=AnsiString(cho);
delete(cho);
 return out;
}

Прав был  sergej.z про \0,  решение предложил уже почти готовое  Artemon : 
Цитата

символы '\0' заменял на '\r\m'

А с char или String ты работаешь не суть важно. Лучше делать универсально, а универсально(чтобы везде не париться с char*) - это как  Artemon предлагал. 

Автор: sergejzr 31.5.2006, 10:07
Цитата(takedo @  31.5.2006,  07:35 Найти цитируемый пост)
А с char или String ты работаешь не суть важно.

Вообще, информация в закодированном виде уже не String, а ByteArray или попросту Blob. Я бы не стал из него AnsiString делать.  

Автор: mr.Anderson 31.5.2006, 16:33
так... вопрос: в качестве ключа может быть передан только один символ? Или несколько? 

Автор: _hunter 31.5.2006, 17:09
учитывая что ксориш ты один символ -- ключ длиннее байта -- изилишен. 

Автор: sergejzr 31.5.2006, 17:17
_hunter, сорри, ты не прав. Здесь как раз защищённость зависит от длинны ключа. 
Ключ в 1 байт означает 256 проверок и открытый текст у тебя.
Ключ длинной в сам текст означает, что подобрать его можно будет только перебором. 

Автор: _hunter 31.5.2006, 17:36
и как ты собираешся записать результат шифрования ключем длинной в текст в один байт?

если увеличивать длину ключа, нужно и размер одного элемента увеличивать 

Автор: sergejzr 31.5.2006, 17:45
Цитата(_hunter @  31.5.2006,  15:36 Найти цитируемый пост)
и как ты собираешся записать результат шифрования ключем длинной в текст в один байт?

Почему?
Длина результата шифрования = длине исходного текста.  

Автор: mr.Anderson 31.5.2006, 18:05
Вот, оказывается, в чем проблема. По моему коду не шифруются те символы, которые содержатся в ключе! 

Автор: sergejzr 31.5.2006, 18:27
Цитата(sim7 @  31.5.2006,  16:05 Найти цитируемый пост)
Вот, оказывается, в чем проблема. По моему коду не шифруются те символы, которые содержатся в ключе!  

Блин, конечно нет, ведь туда 0 записывается, что для AnsiString означает конец строки. Я же говорю, пиши в char* и запоминай длину! 

Автор: _hunter 31.5.2006, 18:31
Цитата(sergej.z @  31.5.2006,  17:45 Найти цитируемый пост)
Длина результата шифрования = длине исходного текста. 

ты, чтоли, последовательно ксорить предлагаеш?
 -- тоже вариант... 

Автор: mr.Anderson 31.5.2006, 18:31
но как ее решить-то? 

Автор: sergejzr 31.5.2006, 19:04
Писал без компилера так что может чтото не работать

Код

AnsiString XOR_Crypt(AnsiString Key, char* InStr, char *result, int length)
{ 
//////////////////////////
 for (int x=0;x<length;x++) 
 result[x]= (InStr[x] ^ Key[x%Key.Length()]);
//////////////////////////
}

int main()
{

AnsiString InStr="my secret message";
AnsiString Key="myKey";

char* result=new char[InStr.Length()];
XOR_Crypt(Key, InStr.c_str(),result, InStr.Length());

//result теперь - закоденная строка

XOR_Crypt(Key,result, result, InStr.Length());
AnsiString out=AnsiString(cho);

//out теперь исходная строка

}
 

Автор: Нитонисе 12.1.2010, 20:11
Код

AnsiString XOR_Crypt(AnsiString InStr, AnsiString Key)
{
 AnsiString out="";

 for (int x=1;x<InStr.Length()+1;x++)
  out += (char)(InStr[x] ^ Key[x%Key.Length()+1]);

 return out;
}

Вот в этом коде, да и в других вариантох функции XOR-шифрования есть такая конструкция Key[x%Key.Length()+1].
Допустим вызываем функцию XOR_Crypt("abcdefgh","12345").
Идем по циклу. При x=4 получится что индекс строки Key будет равен 9, то есть Key[9], но ведь в Key всего 5 символов. Ошибка?

Автор: xvr 13.1.2010, 13:00
Цитата(Нитонисе @ 12.1.2010,  20:11)
Вот в этом коде, да и в других вариантох функции XOR-шифрования есть такая конструкция Key[x%Key.Length()+1].
Допустим вызываем функцию XOR_Crypt("abcdefgh","12345").
Идем по циклу. При x=4 получится что индекс строки Key будет равен 9, 

Это с какого перепугу он будет 9?  smile 4 % 5 + 1  будет 5
Цитата

Ошибка?
Угу, операция '%' - это остаток от деления, а не что то другое  smile 

Автор: Нитонисе 13.1.2010, 13:33
точно) я почему-то подумал, что оператор % - это мы получаем дробную часть)

Автор: NYX 20.1.2010, 14:43
Очередное сори за подъем старой темы. Вообще XOR шифрование самое убогое smile его мона взять тока за основу. При шифровании методом XOR, надо учесть не один нюанс:
1 - строка A должна быть того же размера что и строка B
2 - символ Аn != Bn (иначе потеря данных)

Лично я как то пытался сделать шифрование по XOR методу, но исключительно шифрование ограничивалось массивами суммой которых являлось одно число и сортировка массивов была
разной. 
То есть например есть массив N элементы которого равны N1 = N0+1
Затем производил сортировку типа: x = N[i]; N[N[x]] += z; N[N[x]] -= z; (примерно)
После чего строки мона было XOR'ить smile

Но самый лучший метод который мне понравился, это когда заранее определенный массив состоящий из N1 = N0+1 изначально, сортировался по маске значений пароля, затем входящий поток 
шифровался простым return Table[InValue]; Это на мой взгляд и быстро и весьма широкие границы воображения открывает smile

Автор: Жанерке 24.10.2011, 13:47
объясните плиз xor шифрование ааааа
вообще как шифровать слово

Добавлено через 1 минуту и 23 секунды
procedure TForm1.Button2Click(Sender: TObject);
   var FName: string;
begin

      if OpenDialog1.Execute then
       begin
        FName := OpenDialog1.FileName;
        Memo1.Lines.LoadFromFile(FName);
       end;
end;

procedure TForm1.Button1Click(Sender: TObject);
  var j: integer;
  key, text, longkey, result: string;
  i: integer;
  toto, c: char;
begin


        if edit1.Text='' then  Application.MessageBox('Вкажіть код!', ä!','Помилка!')
         else
         begin
              if Memo1.Lines.Count=0 then  Application.MessageBox('Відсутній код!','Помилка!!!')
                 else
                 begin

                   key:=Edit1.Text;
                   for j:=0 to Memo1.Lines.Count do
                    begin

                      text:=Memo1.Lines.Strings[j];

                      for i := 0 to (length(text) div length(key)) do
                        longkey := longkey + key;
                        for i := 1 to length(text) do
                        begin
                          toto := chr((ord(text[i]) xor ord(longkey[i]))); // XOR алгоритм
                          result := result + toto;
                        end;
                      Memo1.Lines.Strings[j]:=result;
                      end;
                   //zapuskaesh codirovanie
                 end;
         end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var FName: string;
begin
if SaveDialog1.Execute then
       begin
        FName := SaveDialog1.FileName;
        Memo1.Lines.savetofile(FName);
       end;

end;

end.
че за программа

Автор: cutwater 24.10.2011, 16:19
Цитата(Жанерке @  24.10.2011,  12:47 Найти цитируемый пост)
объясните плиз xor шифрование ааааа
вообще как шифровать слово


Прежде объясните каким простите концом тот ваш код на Delphi (к тому же не оформленный как код) относится к С++

По теме
http://lmgtfy.com/?q=xor+%D1%88%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5


Автор: SVN74 24.10.2011, 19:26
Простейший  алгоритм кодирования…
Код

void SimpleCodeByKey(char *Buff, unsigned int Size, char* KeyW)
{
    int Sz = strlen(KeyW);
    for(unsigned int i=0;i<Size;i++)
    Buff[i] = char(Buff[i] ^ KeyW[i % Sz]);
}


Пример  использования с проверкой переноса строк:
Код

// Создаем буфер и копируем в него наш текст из Memo1
    int MyBuffSize = Memo1->Text.Length()+1;
    char *MyBuffer = new char[MyBuffSize];
    strcpy(MyBuffer, Memo1->Text.c_str());

    // Кодируем наш буфер
    SimpleCodeByKey(MyBuffer, MyBuffSize, "Наш ключ = Ася");

    //Смотрим на наш перевернутый буфер
    Memo1->Lines->Add("==== После кодирования ====");
    Memo1->Lines->Add(AnsiString(MyBuffer));

    // Раскодируем наш буфер
    SimpleCodeByKey(MyBuffer, MyBuffSize, "Наш ключ = Ася");

    //Снова смотрим на наш перевернутый буфер
    Memo1->Lines->Add("==== После раскодирования ====");
    Memo1->Lines->Add(AnsiString(MyBuffer));


Автор: koroplysov 3.11.2011, 10:12
Возьмите наш ГОСТ 28147-89 и шифруйте на здоровье. В режиме гаммирования получите текст той же длинны. И надежно и просто. Операции там примитивные:побитовое исключающее или, сложение по модулю 2 в степени 32(просто не учитывай перенос при сложении беззнаковых 32-битных), сдвиг в лево на 11 бит и таблица замен. Пишится легко как на C++ так и на ассемблере(вставка для билдера). Сейчас с собой нет кода, но если нужно, то с удовольствием поделюсь. Есть и другие алгоритмы.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)