Алгоритм генерации огромного списка слов - PullRequest
4 голосов
/ 01 ноября 2009

Хорошо, я знаю, что это будет звучать плохо, как будто я собираюсь использовать это для неэтичных вещей, но у вас есть слово, что я не такой.

Я пишу статью для своего курса по компьютерной и информационной безопасности и выбрал тему хэширования. Один из моментов, которые я подчеркиваю в своей статье, это то, что MD5 является односторонним, и единственный способ взломать MD5-хеш - это непрерывно создавать строки и использовать функцию MD5, а затем сравнивать его с хэшем, который вы хотите взломать. 1003 *

Я хотел бы создать действительно простую макетную программу, чтобы показать ее рядом с моим докладом (мы делаем презентацию, и это было бы здорово), поэтому я хотел разработать алгоритм, который создает строку с каждым возможна комбинация символов до 8 символов. Например, вывод будет:

a, b, c, ..., aa, ab, ac, ... ba, bb, bc и т. Д. И т. Д. И т. П.

Это должно включать буквы, цифры и символы, если это возможно.

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

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

Спасибо. :)

Ответы [ 5 ]

6 голосов
/ 01 ноября 2009

В Python itertools.product делает почти все, что вам нужно - хотя он делает это только за одно «количество повторений», поэтому вам придется выполнять итерации от 1 до 8 (не сложно; -). По сути:

import itertools
import string

# whatever you wish as alphabet (lower/upper, digits, punct, &c)
myalphabet = string.ascii_lowercase + string.ascii_digits

def prods(maxlen, alphabet=myalphabet):
  for i in range(1, maxlen+1):
    for s in itertools.product(alphabet, repeat=i):
      yield ''.join(s)

Конечно, для алфавита длиной N и K повторений (8 в вашем случае) это дает N + N ^ 2 + ... + N ^ K возможностей (2 901 713 047 668 возможностей для N = 36 и K = 8) Но что за несколько триллионов выводов среди друзей! -)

3 голосов
/ 01 ноября 2009

Для реализации этого я бы, вероятно, закодировал бы целые числа в основание 36 (или больше, если вы хотели символы).

1 = 1 2 = 2 ... а = 10 б = 12 ..

и т. Д.

тогда у вас будет число, например 38, и вы сделаете несколько делений, например:

38/36 = 1 остаток 2 = 12 в базе 36

затем просто запустите цикл for до максимального числа, которое вы хотите кодировать, что-то очень большое, и выведите ваши закодированные числа.

просто для удовольствия я написал это для вас: http://pastebin.antiyes.com/index.php?id=327

1 голос
/ 01 ноября 2009

Это неправда, что «единственный способ взломать хеш MD5» - это генерировать каждую возможную строку и искать коллизии. Фактически, если у вас есть доступ к оригиналу, его можно изменить так, чтобы его MD5 совпадал с другим файлом, который вы можете создать. Это описано в статье на infosec.edu .

Даже если вы не можете изменить исходный файл, существуют радужные таблицы контрольных сумм MD5, которые можно использовать для генерации коллизий.

Эти факты делают MD5 непригодным для паролей или криптографии, и фактически правительство США запретило его дальнейшее использование для защищенных приложений.

0 голосов
/ 01 ноября 2009

Чтобы завершить публикацию с примером Java, который распечатает закодированные в Base64 MD5 всех возможных комбинаций символов, используя только символы 0-9 и a-z:

MessageDigest digest = MessageDigest.getInstance("MD5");
int i = 0;
while (true)
{
    String raw = Integer.toString(i, Character.MAX_RADIX);
    byte[] md5 = digest.digest(raw.getBytes());
    String base64 = new BigInteger(1, md5).toString(16);
    System.out.println(raw + " = " + base64);
    i++;
}
0 голосов
/ 01 ноября 2009

Если у вас уже есть доступ к хешированной версии пароля, то MD5 не работает с . Тем не менее, когда дело доходит до взлома хэшированного значения, вам, вероятно, будет лучше использовать Радужные таблицы , словарные атаки и Социальная инженерия над своим грубым помощником силовой метод. Тем не менее, поскольку вы запросили алгоритм для генерации всех значений, возможно, будет полезно следующее (C #):

using System;
using System.Text;

namespace PossibiltyIterator
{
  class Program
  {
    static readonly char[] Symbols = {
      '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', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
      'I', 'J', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 
      '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '@', '#', '$', '%', '^', '&', 
      '*', '(', ')', '-', '_', '+', '=', '/', '\\', '[', ']', '{', '}', ';', ':', '\'', '"', 
      ',', '.', '<', '>', '?', '`', '~'
    };

    const int MaxLength = 8;

    static void BuildWord(int currentLength, int desiredLength, char[] word)
    {
      if (currentLength == desiredLength)
      {
        Console.WriteLine(word);
      }
      else
      {
        for (int value = 0; value < Symbols.Length; ++value)
        {
          word[currentLength] = Symbols[value];
          BuildWord(currentLength + 1, desiredLength, word);
        }
      }
    }

    static void Main(String[] args)
    {
      double totalValues = (Math.Pow(Symbols.Length, MaxLength + 1) - Symbols.Length)/(Symbols.Length - 1);
      Console.WriteLine("Warning! You are about to print: {0} values", totalValues);
      Console.WriteLine("Press any key to continue...");
      Console.ReadKey(true /* intercept */);

      for (int desiredLength = 1; desiredLength <= MaxLength; ++desiredLength)
      {
        BuildWord(0 /* currentLength */, desiredLength, new char[MaxLength]);
      }
    }

  }
}

Если честно, это можно оптимизировать дальше. Поскольку он строит все «слова» длины 1, тогда это работает второй раз при построении слов длины 2. Было бы разумнее построить слова длины MaxLength, а затем обрезать одну букву для построения слова MaxLength. 1.

Вот оптимизированная версия ... обратите внимание, что она НЕ возвращает слова в первоначально запрошенном порядке.

using System;
using System.Text;

namespace PossibiltyIterator
{
  class Program
  {
    static readonly char[] Symbols = {
      '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', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
      'I', 'J', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 
      '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '@', '#', '$', '%', '^', '&', 
      '*', '(', ')', '-', '_', '+', '=', '/', '\\', '[', ']', '{', '}', ';', ':', '\'', '"', 
      ',', '.', '<', '>', '?', '`', '~'
    };

    const int MaxLength = 8;

    static void BuildWord(int currentLength, int desiredLength, char[] word)
    {
      if (currentLength != desiredLength)
      {
        for (int value = 0; value < Symbols.Length; ++value)
        {
          word[currentLength] = Symbols[value];
          BuildWord(currentLength + 1, desiredLength, word);
        }
        word[currentLength] = '\0';
      }

      Console.WriteLine(word);
    }

    static void Main(String[] args)
    {
      double totalValues = (Math.Pow(Symbols.Length, MaxLength + 1) - Symbols.Length)/(Symbols.Length - 1);
      char[] word = new char[MaxLength];

      Console.WriteLine("Warning! You are about to print: {0} values", totalValues);
      Console.WriteLine("Press any key to continue...");
      Console.ReadKey(true /* intercept */);

      BuildWord(0 /* currentLength */, MaxLength, new char[MaxLength]);
    }

  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...