Rot13 для чисел

Хотя CRC, инициализированный в ноль, не подвержен влиянию начальных нулей, если во время передачи какой-либо из этих ведущих нулей станет ненулевым из-за ошибки, он обнаружит ошибку. Чего он не поймает, так это укороченного сообщения, в котором некоторые ведущие нули удаляются из сообщения, что приводит к укороченному сообщению, что может быть проблемой, если нет отдельной проверки длины. Использование всех поймает такое сокращенное сообщение. Фактически любой ненулевой начальный CRC будет перехватывать сокращенное сообщение. Все просто удобно. Одним из вариантов является использование CRC, сгенерированного из короткого шаблона данных из всех, для начального значения, например, 16-битные биты, используемые в качестве данных для 16-битного CRC для генерации начального CRC (это будет константа, поэтому вычисляется заранее), что будет эквивалентно добавлению данных со всеми 1 битами и инициализации CRC равным 0.

12
задан dreeves 1 June 2010 в 03:28
поделиться

13 ответов

Here's a solution inspired by Svante's answer.

M = 9999  # Upper bound on bid.
seal(x) = M * randInt(9,99) + x
unseal(x) = x % M

Sanity check:

> seal(7)
716017
> seal(7)
518497
> unseal(seal(7))
7

This needs tweaking to allow negative bids though:

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

A nice thing about this solution is how trivial it is for the recipient to decode -- just mod by 9999 (and if that's 5000 or more then it was a negative bid so subtract another 9999). It's also nice that the obscured bid will be at most 6 digits long. (This is plenty security for what I have in mind -- if the bids can possibly exceed $5k then I'd use a more secure method. Though of course the max bid in this method can be set as high as you want.)

Instructions for Lay Folk

Pick a number between 9 and 99 and multiply it by 9999, then add your bid. This will yield a 5 or 6-digit number that encodes your bid. To unseal it, divide by 9999, subtract the part to the left of the decimal point, then multiply by 9999. (This is known to children and mathematicians as "finding the remainder when dividing by 9999" or "mod'ing by 9999", respectively.)

This works for nonnegative bids less than 9999 (if that's not enough, use 99999 or as many digits as you want). If you want to allow negative bids, then the magic 9999 number needs to be twice the biggest possible bid. And when decoding, if the result is greater than half of 9999, ie, 5000 or more, then subtract 9999 to get the actual (negative) bid.

Again, note that this is on the honor system: there's nothing technically preventing you from unsealing the other person's number as soon as you see it.

6
ответ дан 2 December 2019 в 04:43
поделиться

Is there a maximum bid? If so, you could do this:

Let max-bid be the maximum bid and a-bid the bid you want to encode. Multiply max-bid by a rather large random number (if you want to use base64 encoding in the last step, max-rand should be (2^24/max-bid)-1, and min-rand perhaps half of that), then add a-bid. Encode this, e.g. through base64.

The recipient then just has to decode and find the remainder modulo max-bid.

4
ответ дан 2 December 2019 в 04:43
поделиться

Вы можете упаковать свой номер как 4-байтовый с плавающей точкой вместе с другим случайным с плавающей точкой в ​​двойник и отправить его. Затем клиент просто должен забрать первые четыре байта. В python:

import struct, random
def seal(f):
   return struct.unpack("d",struct.pack("ff", f, random.random() ))[0]
def unseal(f):
   return struct.unpack("ff",struct.pack("d", f))[0]

>>> unseal( seal( 3))
3.0
>>> seal(3)
4.4533985422978706e-009
>>> seal(3)
9.0767582382536571e-010
7
ответ дан 2 December 2019 в 04:43
поделиться

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

Если вы хотите дать двум людям, Бобу и Алисе, половину ключа каждому что только при объединении их они смогут открывать любые замки с ключами, как ты это делаешь? Решение этого приходит из математики. Скажем, у вас есть две точки A (-2,2) и B (2,0) в системе координат ax / y.

               |
       A       +
               |
               C
               |
---+---+---+---|---+---B---+---+---+---
               |
               +
               |
               +

Если вы проведете прямую линию между ними, она пересечет ось y ровно в одной точке, C (0,1). Если вы знаете только одну из точек A или B, невозможно сказать, где она будет пересекаться. Таким образом, вы можете позволить точкам A и B быть общими ключами, которые при объединении покажут значение y точки пересечения (т.е. 1 в этом примере), и это значение затем обычно используется как реальный ключ к чему-то.

Для вашего приложения ставок вы можете позволить seal () и unseal () поменять местами y-значения между точками C и B. (детерминированный), но время от времени точка A меняется.

Таким образом, печать (значение y точки B) даст совершенно разные результаты в зависимости от точки A, но unseal (печать (значение y точки B)) должно возвращать значение y B, которое вы и просили.

PS Не обязательно иметь A и B по разные стороны от оси y, но концептуально гораздо проще думать об этом таким образом (и я рекомендую реализовать это таким образом).

С помощью этой прямой линии вы можете затем разделить ключи между несколькими людьми, так что только два из они нужны, чтобы разблокировать что угодно. Можно использовать типы кривых, отличные от прямых, чтобы создать другое свойства совместного использования ключей (т.е. требуется 3 из 3 ключей и т. д.).

1
ответ дан 2 December 2019 в 04:43
поделиться

Pseudo code:

encode:

value = 2000
key = random(0..255); // our key is only 2 bytes

// 'sealing it'
value = value XOR 2000;

// add key
sealed = (value << 16) | key

decode:

key = sealed & 0xFF
unsealed = key XOR (sealed >> 16)

Would that work?

1
ответ дан 2 December 2019 в 04:43
поделиться

Если вы полагаетесь на честность пользователя и имеете дело только с целочисленными ставками, вам может понадобиться простая операция XOR со случайным числом, например в C #:

static Random rng = new Random();

static string EncodeBid(int bid)
{
    int i = rng.Next();
    return String.Format("{0}:{1}", i, bid ^ i);
}

static int DecodeBid(string encodedBid)
{
    string[] d = encodedBid.Split(":".ToCharArray());
    return Convert.ToInt32(d[0]) ^ Convert.ToInt32(d[1]);
}

Использовать :

int bid = 500;
string encodedBid = EncodeBid(bid); // encodedBid is something like 54017514:4017054 and will be different each time
int decodedBid = DecodeBid(encodedBid); // decodedBid is 500

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

4
ответ дан 2 December 2019 в 04:43
поделиться

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

0
ответ дан 2 December 2019 в 04:43
поделиться

You could set a different base (like 16, 17, 18, etc.) and keep track of which base you've "sealed" the bid with...

Of course, this presumes large numbers (> the base you're using, at least). If they were decimal, you could drop the point (for example, 27.04 becomes 2704, which you then translate to base 29...)

You'd probably want to use base 17 to 36 (only because some people might recognize hex and be able to translate it in their head...)

This way, you would have numbers like G4 or Z3 or KW (depending on the numbers you're sealing)...

0
ответ дан 2 December 2019 в 04:43
поделиться

Вот дешевый способ получить выгоду от rot13:

Предположим, у нас есть функция gibberish (), которая генерирует что-то вроде «fdjk alqef lwwqisvz», и функция слов (x), которая преобразует число x к словам, например, слова (42) возвращают «сорок два» (без дефисов).

Затем определите

seal(x) = rot13(gibberish() + words(x) + gibberish())

и

unseal(x) = rot13(x)

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

Проверка работоспособности:

> seal(7)
fhrlls hqufw huqfha frira afsb ht ahuqw ajaijzji
> seal(7)
qbua adfshua hqgya ubiwi ahp wqwia qhu frira wge
> unseal(seal(7))
sueyyf udhsj seven ahkua snsfo ug nuhdj nwnvwmwv

Я знаю, что это глупо, но это способ сделать это «вручную», если у вас есть только rot13.

0
ответ дан 2 December 2019 в 04:43
поделиться

Знаете ли вы, что вам нужен больший «запечатанный» набор чисел, чем ваш оригинал, если вы хотите, чтобы это работало?

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

2
ответ дан 2 December 2019 в 04:43
поделиться

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

from random import randint

def seal(input):
    r = randint(0, 50)
    obfuscate = [str(r)] + [ str(ord(c) + r) for c in '%s' % input ]
    return ':'.join(obfuscate)

def unseal(input):
    tmp = input.split(':')
    r = int(tmp.pop(0))
    deobfuscate = [ chr(int(c) - r) for c in tmp ]
    return ''.join(deobfuscate)

# I suppose you would put your bid in here, for 100 dollars
tmp = seal('$100.00') # --> '1:37:50:49:49:47:49:49' (output varies)
print unseal(tmp) # --> '$100.00'

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

1
ответ дан 2 December 2019 в 04:43
поделиться

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

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

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

[править] Поскольку вы доверяете другому клиенту:

Sender:
Let M be your message
K = random 4-byte key
C1 = M xor hash(K) //hash optional: hides patterns in M xor K
//(you can repeat or truncate hash(K) as necessary to cover the message)
//(could also xor with output of a PRNG instead)
C2 = K append M //they need to know K to reveal the message
send C2 //(convert bytes to hex representation if needed)

Receiver:
receive C2
K = C2[:4]
C1 = C2[4:]
M = C1 xor hash(K)
4
ответ дан 2 December 2019 в 04:43
поделиться

Один простой способ - написать сообщение типа:

«моя ставка: $ 14,23: aduigfurjwjnfdjfugfojdjkdskdfdhfddfuiodrnfnghfifyis»

Все это барахло генерируется случайным образом 12 и каждый раз отличается

. ] Отправьте другому человеку хэш SHA256 сообщения. Пусть они отправят вам хэш своей ставки. Затем, когда у вас обоих есть хэши, отправьте полное сообщение и подтвердите, что их ставка соответствует хешу, который они вам дали.

Это дает довольно сильные гарантии, чем вам нужно - на самом деле они не могут рассчитать вашу ставку. прежде чем отправить им свое полное сообщение. Однако, как вы описываете, функции unseal () не существует.

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

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

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

Если, как вы говорите, вы хотите, чтобы они могли восстановить вашу ставку без какого-либо дополнительного вмешательства с вашей стороны, и вы готовы доверять им только сделать это после публикации заявки, а затем просто зашифровать с помощью любого старого симметричного шифра (возможно, gpg --symmetric ) и ключа «rot13». Это предотвратит случайное мошенничество, но допустит необнаружимый мошенничество.

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

Если, как вы говорите, вы хотите, чтобы они могли восстановить вашу ставку без какого-либо дополнительного вмешательства с вашей стороны, и вы готовы доверять им только сделать это после публикации заявки, а затем просто зашифровать с помощью любого старого симметричного шифра (возможно, gpg --symmetric ) и ключа «rot13». Это предотвратит случайное мошенничество, но допустит необнаружимый мошенничество.

2
ответ дан 2 December 2019 в 04:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: