Вот решение, вдохновленное ответом Сванте.
M = 9999 # Upper bound on bid.
seal(x) = M * randInt(9,99) + x
unseal(x) = x % M
Проверка работоспособности:
> seal(7)
716017
> seal(7)
518497
> unseal(seal(7))
7
Это требует настройки, чтобы разрешить отрицательные ставки:
M = 9999 # Numbers between -M/2 and M/2 can be sealed.
seal(x) = M * randInt(9,99) + x
unseal(x) =
m = x % M;
if m > M/2 return m - M else return m
Хорошая вещь в этом решении заключается в том, насколько легко получателю декодировать - просто мод на 9999 (а если это 5000 или больше, то это была отрицательная ставка, поэтому вычтите еще 9999). Также приятно, что скрытая ставка будет иметь длину не более 6 цифр. (Это достаточная безопасность для того, что я имею в виду - если ставки могут превышать 5 тыс. Долларов, я бы использовал более безопасный метод. Хотя, конечно, максимальная ставка в этом методе может быть установлена настолько высокой, насколько вы захотите.)
Инструкция для мирян
Выберите число от 9 до 99 и умножьте его на 9999, затем добавьте ставку.
Это даст 5 или 6-значный номер, который кодирует вашу ставку.
Чтобы распечатать его, разделите на 9999, вычтите часть слева от десятичной точки, затем умножьте на 9999.
(Это известно детям и математикам как «поиск остатка при делении на 9999» или «изменение на 9999» соответственно.)
Это работает для неотрицательных ставок менее 9999 (если этого недостаточно, используйте 99999 или столько цифр, сколько хотите).
Если вы хотите разрешить отрицательные ставки, то магическое число 9999 должно быть в два раза больше максимально возможной ставки.
А при декодировании, если результат больше половины 9999, то есть 5000 или более, вычтите 9999, чтобы получить фактическую (отрицательную) ставку.
Опять же, обратите внимание, что это относится к системе чести: технически ничто не мешает вам открыть номер другого человека, как только вы его увидите.