Мне дали зашифрованный файл, в котором открытый текст имеет "общий (но не очень распространенный в наши дни)" формат . ~ 80000 байт
Он был зашифрован с помощью того, что я бы назвал шифром Vigenere с модифицированной таблицей шифрования. Один байт ключа и один байт открытого текста отображаются на один байт зашифрованного текста.
Строка ключей имеет определенную длину, поэтому ключевой символ, используемый для шифрования, циклически перебирает строку ключей.
Ключ содержит только буквенно-цифровые символы.
Пока что я определил, что длина ключа составляет 30/60, найдя наименее общий делитель начальной позиции повторяющихся троек в зашифрованном тексте. Довольно стандартно для Vigenere.
Теперь я угадывал возможные символы для ключа, наблюдая за тем, какими будут расшифрованные байты, и исключая возможности, если они выходят за пределы допустимых диапазонов (поскольку 32-126 являются видимыми, никаких значений между 16-31 и т. Д. .)
Это работало для первой части, у которой был маленький ключ, и открытый текст был прямым ASCII.
Когда я пробую его для файла большего размера и «нового формата файла», он отклоняет все возможные символы.
Это исключает ASCII, Ascii85, Base64, windows-1252, utf-7, QP и uuencode, поскольку все они полагаются на набор символов ASCII. Я также сделал фильтры для EBCDIC и ISO8859-1, которые отклонили все ключи. Utf-8 также не удалось, потому что ни один ключ не заставил бы все байты начинаться с 0,10,110,1110,11110,111110 или 1111110.
Остальные кодировки, которые я не пробовал, я подозреваю, это UTF-16,32,1, и я не уверен, как их фильтровать.
Мои вопросы:
- Есть ли другие кодировки символов, которые я забыл?
- Возможно ли, что я отфильтровываю слишком много, и что некоторые из связанных символов должны проскальзывать?
- Может ли формат файла означать что-то кроме кодировки символов? если да, то как мне согласовать это с фильтром, все еще работающим на символах ASCII?
- Что если формат файла означает сжатый или заархивированный?
Вот код фильтрации, который я использую, фильтр меняется в зависимости от того, что я пытаюсь отсеять.
void guessCrypt(string fileName, int keyLength, int index)
{
byte[] file = cast(byte[])read(fileName);
foreach(key;ValidKeyChars)
{
bool work = true;
for(int x = index; x < file.length-10; x+=keyLength)
{
byte single = file[x];
int res = sdecrypt(single,key);
if ((res < 32 && res > 15) || res > 126) //FILTER - this one ASCII
{
work = false;
break;
}
}
if (work == true)
{
writefln("\nwork: %s",key);
}
}
}