Найдите случайную точку на линии

Я пишу небольшую программу, чтобы помочь разделить пароли (объяснение см. Ниже)

У меня есть код для преобразования текста в int (двоичный текст ascii -> dec int)

так что в этом случае слово "тест" будет = 1952805748

Теперь самое интересное. (Кодировка пароля)

Тогда я бы взял x1 = 1952805748 и y1 = 0

затем я создаю случайную точку, где x2 = 7 и y2 = 142

это проведет линию между x1, y1 и x2, y2 (используя Y = mx + B)

Мне нужно найти любую случайную точку на линии, которую создают эти две точки (назовите это x3, y3)

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

++ Почему ++

общая идея заключается в том, что если вам пришлось разделить пароль между двумя сторонами, одна сторона могла бы определить пароль на основе строки, которую им дали

если вы используете этот метод, каждый из них получит по одной точке, и из этой единственной точки будет математически невозможно определить, где линия пересекает x (x =? y = 0), чтобы вы могли чувствовать себя в безопасности, передавая один набор баллов своему юристу и один твоей жене

они будут делать математику (вводя его в программу), затем они получат число, которое будет декодировано, чтобы сказать пароль, который может расшифровать файл с вашей волей или каким-либо другим чувствительным документом, к которому вы не хотите, чтобы они получали доступ без другого присутствующий

Ответов (5)

Решение

Этот алгоритм на самом деле называется « Обмен секретами Шамира » и является действительно хорошим способом разделения секретов. Вы можете разделить произвольно большие секреты, что потребует любого количества людей, которых вы хотите собрать вместе, чтобы восстановить секрет.

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

Псевдокод в Википедии, однако, хорош только для чисел с плавающей запятой, и его необходимо немного изменить для использования с целыми числами. Ознакомьтесь с моей полной реализацией Python, если вам нужны некоторые идеи (и при условии, что это вообще полезно).

Это дает мне такой результат:

1 -- 50383220533284199945706810754936311181214547134666382315016772033813961148457676
2 -- 125723425896904546349739165166331731432281836699962161072279259011758052396215820
3 -- 235794378436564714387676526976517945151880763730707233042654663244625708155520494
'This is my super secret password.'

Изменить: год спустя я обновил реализацию, чтобы она работала в ограниченном поле, которое требуется для обеспечения доказуемой безопасности. Ура!

Не нужно было бы искать какую-то неизвестную координату ... Достаточно просто вставить ваш зашифрованный файл в генератор последовательных чисел. Вы значительно снизили сложность перебора шифрования в несколько раз. Вместо того, чтобы каждый символ был 1 из ~ 94 (вводимые символы на стандартной клавиатуре), вы уменьшили его до 1 из 10 (1 из 11, если вы разрешаете десятичные дроби).

Я бы не советовал использовать этот метод. Как упоминал Скитер, просто дважды зашифруйте файл.

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

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

Plaintext -> Encrypted1 (with password 1)
Encrypted1 -> Encrypted2 (with password 2)

Encrypted2 это то, что вы храните. Выбросьте Encrypted1 .

Чтобы расшифровать, просто расшифруйте Encrypted2 пароль 2, чтобы получить Encrypted1, затем расшифруйте, Encrypted1 чтобы вернуться к открытому тексту.

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

РЕДАКТИРОВАТЬ: В качестве еще более простого решения просто придумайте действительно длинный пароль и дайте каждой стороне его половину. Например, зашифруйте файл ключом «это очень длинный пароль» и дайте вашему широкому «это очень» и вашему юристу «длинный пароль». Очевидно, вам нужно правильно выбрать пароль, чтобы знание одной половины не давало никаких намеков на другую.

Если ваши конечные точки (x1, y1) и (x2, y2), и у вас есть случайное число r в диапазоне от 0 до 1, точка вдоль линии будет:

(x1+(x2-x1)*r,y1+(y2-y1)*r)

С заданными вами конечными точками (1952805748,0) и (7,42) со случайным значением 0,5 (на полпути вдоль линии) вы получите:

(976402877.5,21)

которую вы можете легко обработать как среднюю точку. Вы можете округлить любые координаты, если вам нужны целые числа.

После вашего комментария (перефразировано):

I may not have explained this properly: one person would be given (x1,y1) different person would be given (x3,y3). At no point would a person be able to take a single point and figure out where the line crosses x (N,0).

Учитывая, что ваш (x1, y1) был (1952805748,0), тот, кто знает пересечение оси x (поскольку y = 0). Похоже, вам нужны две точки вдоль линии, где ни одна не находится на оси x. Это означает, что одной стороне должна быть указана ваша случайно выбранная конечная точка (7,42), а другой стороне - ваша случайная точка на линии (976402877,5,21) - ни одна из этих точек не должна иметь нулевое значение y. Этого можно добиться, убедившись, что случайное значение находится в диапазоне от 0,2 до 1,0, а не от 0,0 до 1,0 (при условии, что ваш y1 всегда равен 0).

Ни одна из сторон не могла определить пересечение оси x с их одной координатой, но две координаты вместе дадут вам эту информацию.

Кроме того, в этом случае округление или ординаты не подходят, вам придется сопоставить их, например, (976402877,5,21) стать (1952805755,42) [умножить на 2, что является простейшим целочисленным соотношением].

//Assume x1, x2, and m, b exist as ints
Random r = new Random();
int x3 = r.Next(Math.Min(x1, x2), Math.Max(x1, x2));
int y3 = m * x3 + b;

По сути, мы выбираем некоторый x между двумя x (гарантируя правильный домен и, в соответствии с ограничениями вашей линейной функции, правильный диапазон) и решаем его относительно y. Не так уж и сложно.