Метод шифрования Уитстона "Двойной квадрат"

ITALIANO

Код шифрования у меня реализован, проблема в том, что я не знаю как сделать так, чтобы при выборе RadioButton1 "Русский текст" в StringGrid1 и StringGrid2 выводились рандомно символы, без повторений от а до я и знаки ("," " " ":" "."), а при выборе RadioButton2 "Английский текст" было тоже самое, что и в первом случае, только от a до z и символы ("," " " ":" "." "?" "-" """ "(" ")"). Это всё происходит при выборе RadioButton и нажатие на кнопку "Заполнить таблицы". Что было понятнее скрин программы ниже:
14 ответов

ITALIANO

Перемешивание символов для первого варианта (для второго аналогично, только не забудь для использования " поставить перед ним \, то есть \"):
  #include <algorithm>
 
  //  ..........................................
 
  String alph = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя, :.", test = "";
  const n = 37;  // количество cимволов в alph
  randomize();
  int arr[n], i;
  for (i = 0; i < n; i++)
    arr[i] = i + 1;
  std::random_shuffle(arr, arr + n);
  for (i = 0; i < n; i++)
    test += alph[arr[i]];
  ShowMessage(test);
Вывод в StringGrid по клику на RadioButton, надеюсь, сможешь сам сделать.


ITALIANO

Немного не понятен код... Вот программа, там отдельно есть часть кода про принцеп работы, так нужно связать м/у собой и механику и RadioButton и StringGrid:
// Возвращает позицию символа в таблице
void __fastcall TForm5::findXY( char * aTable, char aCh, int& aX, int& aY )
{
   for( int y = 0; y < 7; y++ ){
      for( int x = 0; x < 5; x++ ){
         if( aTable[y * 5 + x] == aCh ){
            aX = x;
            aY = y;
            return;
         }
      }
   }
 
    // Нет такого символа
   aX = -1;
   aY = -1;
}


ITALIANO

ой не тот код...
// Выполняет преобразование
AnsiString __fastcall TForm5::work( AnsiString aString ){
    // Базовая таблица
   const char BaseTable[7][5] = {
      { 'а', 'б', 'в', 'г','д'  },
      { 'е', 'ж', 'з', 'и', 'к' },
      { 'л', 'м', 'н', 'о', 'п' },
      { 'р', 'с', 'т', 'у', 'ф' },
      { 'х', 'ц', 'ч', 'ш', 'щ' },
      { 'ъ', 'ы', 'ь', 'э', 'ю' },
      { 'я', '.', ',', ':', ' ' }
   };
 
 
    // Степень перемешивания, с которой сформируются исходные таблицы
   const int MixDepth = 1000;
 
   char table[2][7][5];
    // Заполним таблицы
   memcpy( table[0], BaseTable, sizeof( BaseTable ) );
   memcpy( table[1], BaseTable, sizeof( BaseTable ) );
 
    // Перемешаем таблицы
   randomize();
   for( int t = 0; t < 2; t++ ){
      for( int i = 0; i < MixDepth; i++ ){
          // Мешаем первую таблицу
         int y1 = rand() % 7;
         int x1 = rand() % 5;
         int y2 = rand() % 7;
         int x2 = rand() % 5;
         char tmp = table[t][y1][x1];
         table[t][y1][x1] = table[t][y2][x2];
         table[t][y2][x2] = tmp;
      }
   }
 
   int len = aString.Length();
   if( len & 1 ){
       // Добавим пробел
      aString += " ";
      len++;
   }
 
    // Сформируем зашифрованую строку
   AnsiString retVal;
   for( int i = 0; i < len; i++ ){
      int x, y;
      findXY( (char * )BaseTable, aString[i + 1], x, y );
      if( x < 0 || x < 0 ){
         return AnsiString( "Неизвестный символ в позиции " ) + IntToStr( i + 1 );
      }
      retVal += table[i & 1][y][x];
   }
 
   return retVal;
}
а как тогда совместить стринггрид с радибаттоном и функцией шифрования...посмотрите программу, пожалуйста мне только осталось разобраться с двойным квадратом...как реализовать вывод символов из кода в таблицы?


ITALIANO

  String alph = "абвгдежзиклмнопрстуфхцчшщъыьэюя, :.", test = "";
  const n = 35;  // количество cимволов в alph
  const k = 5;  // количество столбцов в таблице
  randomize();
  int arr[n], i;
  for (i = 0; i < n; i++)
    arr[i] = i + 1;
  std::random_shuffle(arr, arr + n);
  for (i = 0; i < n; i++)
    test += alph[arr[i]];
 
  for (i = 0; i < n; i++)
    StringGrid1->Cells[i%k][i/k] = test[i+1];


ITALIANO

а с функцией расшифровки, кто поможет?


ITALIANO

Нужно сделать все то же самое, что делал при шифровке, но в обратном порядке. Грубо говоря, подать на вход шифрованную строку и получить в итоге исходную.


ITALIANO

gunslinger, выдаёт ошибку: 'random_shuffle' is not a member of 'std'пользуюсь builder c++ 6


ITALIANO

Строка (пост №2) для чего?
#include <algorithm>


ITALIANO

gunslinger, на одну таблицу работает, хотел сделать на 2-е, но выбивает какую-то ошибку...
void __fastcall TForm5::Button1Click(TObject *Sender)
{
if (sRadioButton1->Checked)
{  String alph = "Г*áâãäåæçèêëìГ*îïðñòóôõö÷øùúûüýþÿ.,: ", test = "";
  const n = 35;  // êîëè÷åñòâî cèìâîëîâ Гў alph
  const k = 5;  // êîëè÷åñòâî ñòîëáöîâ Гў ГІГ*áëèöå
  randomize();
  int arr[n], i;
  for (i = 0; i < n; i++)
    arr[i] = i + 1;
  std::random_shuffle(arr, arr + n);
  for (i = 0; i < n; i++)
    test += alph[arr[i]];
 
  for (i = 0; i < n; i++)
    StringGrid1->Cells[i%k][i/k] = test[i+1];
    StringGrid2->Cells[i%k][i/k] = test[i+1];
}
if (sRadioButton2->Checked)
{  String alph = "abcdefghijklmnopqrstuvwxyz.,: ?-'()", test = "";
  const n = 35;  // êîëè÷åñòâî cèìâîëîâ Гў alph
  const k = 5;  // êîëè÷åñòâî ñòîëáöîâ Гў ГІГ*áëèöå
  randomize();
  int arr[n], i;
  for (i = 0; i < n; i++)
    arr[i] = i + 1;
  std::random_shuffle(arr, arr + n);
  for (i = 0; i < n; i++)
    test += alph[arr[i]];
 
  for (i = 0; i < n; i++)
    StringGrid1->Cells[i%k][i/k] = test[i+1];
    StringGrid2->Cells[i%k][i/k] = test[i+1];
}
}


ITALIANO

Ошибки надо указывать.Замечания по коду - бездумное копирование не есть хорошо. Плюс у тебя в обеих таблицах получатся одинаковые символы в одних и тех же ячейках. Судя по алгоритму, символы должны быть перемешаны по-разному для разных таблиц. У тебя этого в коде нет.


ITALIANO

gunslinger, не совсем понимаю принцип шифровки... ошибка скорее, в том, что я второй раз указал StrigGrid, только 2...


ITALIANO

Читай теорию: http://vunivere.ru/work24054/page2 Все разжевано и в основном информация только по существу.


ITALIANO

gunslinger, ошибка при добавлении в 2 таблицы с выводом только одной...


ITALIANO

Код:
void __fastcall TForm5::Button1Click(TObject *Sender)
{
if (sRadioButton1->Checked)
{  String alph = "Г*áâãäåæçèêëìГ*îïðñòóôõö÷øùúûüýþÿ.,: ", test = "";
  const n = 35;  // êîëè÷åñòâî cèìâîëîâ Гў alph
  const k = 5;  // êîëè÷åñòâî ñòîëáöîâ Гў ГІГ*áëèöå
  randomize();
  int arr[n], i;
  for (i = 0; i < n; i++)
    arr[i] = i + 1;
  std::random_shuffle(arr, arr + n);
  for (i = 0; i < n; i++)
    test += alph[arr[i]];
 
  for (i = 0; i < n; i++)
    StringGrid1->Cells[i%k][i/k] = test[i+1];
    StringGrid2->Cells[i%k][i/k] = test[i+1];
}
if (sRadioButton2->Checked)
{  String alph = "abcdefghijklmnopqrstuvwxyz.,: ?-'()", test = "";
  const n = 35;  // êîëè÷åñòâî cèìâîëîâ Гў alph
  const k = 5;  // êîëè÷åñòâî ñòîëáöîâ Гў ГІГ*áëèöå
  randomize();
  int arr[n], i;
  for (i = 0; i < n; i++)
    arr[i] = i + 1;
  std::random_shuffle(arr, arr + n);
  for (i = 0; i < n; i++)
    test += alph[arr[i]];
 
  for (i = 0; i < n; i++)
    StringGrid1->Cells[i%k][i/k] = test[i+1];
    StringGrid2->Cells[i%k][i/k] = test[i+1];
}
}
как в этот кусок кода помимо русских букв вставить английские?
void __fastcall TfmMain::findXY( char * aTable, char aCh, int& aX, int& aY ){
   for( int y = 0; y < 7; y++ ){
      for( int x = 0; x < 5; x++ ){
         if( aTable[y * 5 + x] == aCh ){
            aX = x;
            aY = y;
            return;
         }
      }
   }
 
    // Нет такого символа
   aX = -1;
   aY = -1;
}
 
 // Выполняет преобразование
AnsiString __fastcall TfmMain::work( AnsiString aString ){
    // Базовая таблица
   const char BaseTable[7][5] = {
      { 'а', 'б', 'в', 'г','д'  },
      { 'е', 'ж', 'з', 'и', 'к' },
      { 'л', 'м', 'н', 'о', 'п' },
      { 'р', 'с', 'т', 'у', 'ф' },
      { 'х', 'ц', 'ч', 'ш', 'щ' },
      { 'ъ', 'ы', 'ь', 'э', 'ю' },
      { 'я', '.', ',', ':', ' ' }
   };
 
    // Степень перемешивания, с которой сформируются исходные таблицы
   const int MixDepth = 1000;
 
   char table[2][7][5];
    // Заполним таблицы
   memcpy( table[0], BaseTable, sizeof( BaseTable ) );
   memcpy( table[1], BaseTable, sizeof( BaseTable ) );
 
    // Перемешаем таблицы
   randomize();
   for( int t = 0; t < 2; t++ ){
      for( int i = 0; i < MixDepth; i++ ){
          // Мешаем первую таблицу
         int y1 = rand() % 7;
         int x1 = rand() % 5;
         int y2 = rand() % 7;
         int x2 = rand() % 5;
         char tmp = table[t][y1][x1];
         table[t][y1][x1] = table[t][y2][x2];
         table[t][y2][x2] = tmp;
//коtик люцифера
      }
   }
 
   int len = aString.Length();
   if( len & 1 ){
       // Добавим пробел
      aString += " ";
      len++;
   }
 
    // Сформируем зашифрованую строку
   AnsiString retVal;
   for( int i = 0; i < len; i++ ){
      int x, y;
      findXY( (char * )BaseTable, aString[i + 1], x, y );
      if( x < 0 || x < 0 ){
         return AnsiString( "Неизвестный символ в позиции " ) + IntToStr( i + 1 );
      }
      retVal += table[i & 1][y][x];
   }
 
   return retVal;
}
Думал разбить на sRadioButton'ы когда вставляешь в начале функции первый радио баттон, он работает, но второй не ставиться...
AnsiString __fastcall TForm5::work( AnsiString aString ){
    // ГЃГ*çîâГ*Гї ГІГ*áëèöГ*
if(sRadioButton1->Checked){
      const char BaseTable[7][5] = {
      { 'Г*', 'ГЎ', 'Гў', 'ГЈ','Г¤'  },
      { 'ГҐ', 'Г¦', 'Г§', 'ГЁ', 'ГЄ' },
      { 'Г«', 'Г¬', 'Г*', 'Г®', 'ГЇ' },
      { 'Г°', 'Г±', 'ГІ', 'Гі', 'Гґ' },
      { 'Гµ', 'Г¶', 'Г·', 'Гё', 'Г№' },
      { 'Гє', 'Г»', 'Гј', 'ГЅ', 'Гѕ' },
      { 'Гї', '.', ',', ':', ' ' }
      }
   };
 
 
    // ÑòåïåГ*Гј ïåðåìåøèâГ*Г*ГЁГї, Г± êîòîðîé ñôîðìèðóþòñÿ èñõîäГ*ûå ГІГ*áëèöû
   const int MixDepth = 1000;
 
   char table[2][7][5];
    // Г‡Г*ïîëГ*ГЁГ¬ ГІГ*áëèöû
   memcpy( table[0], BaseTable, sizeof( BaseTable ) );
   memcpy( table[1], BaseTable, sizeof( BaseTable ) );
 
    // ÏåðåìåøГ*ГҐГ¬ ГІГ*áëèöû
   randomize();
   for( int t = 0; t < 2; t++ ){
      for( int i = 0; i < MixDepth; i++ ){
          // ГЊГҐГёГ*ГҐГ¬ ïåðâóþ ГІГ*áëèöó
         int y1 = rand() % 7;
         int x1 = rand() % 5;
         int y2 = rand() % 7;
         int x2 = rand() % 5;
         char tmp = table[t][y1][x1];
         table[t][y1][x1] = table[t][y2][x2];
         table[t][y2][x2] = tmp;
      }
   }
 
   int len = aString.Length();
   if( len & 1 ){
       // ÄîáГ*ГўГЁГ¬ ïðîáåë
      aString += " ";
      len++;
   }
 
    // Ñôîðìèðóåì Г§Г*øèôðîâГ*Г*ГіГѕ ñòðîêó
   AnsiString retVal;
   for( int i = 0; i < len; i++ ){
      int x, y;
      findXY( (char * )BaseTable, aString[i + 1], x, y );
      if( x < 0 || x < 0 ){
         return AnsiString( "ÍåèçâåñòГ*ûé ñèìâîë Гў ïîçèöèè " ) + IntToStr( i + 1 );
      }
      retVal += table[i & 1][y][x];
   }
 
   return retVal;
}
}
сама же таблица которую я хочу вставить это
if(sRadioButton2->Checked){
 const char BaseTable[7][5] = {
      { 'a', 'b', 'c', 'd','e'  },
      { 'f', 'g', 'h', 'i', 'j' },
      { 'k', 'l', 'm', 'n', 'o' },
      { 'p', 'q', 'r', 's', 't' },
      { 'u', 'v', 'w', 'x', 'y' },
      { 'z', '.', ',', ':', ' ' },
      { '?', '-', '"', '(', ')' }
   };