Может кто-нибудь объяснить мне, как ( (c-65+k)%26)+65) работает в Цезарь Цифр?
Если c - это числовое значение заглавного символа (т. Е. B равно 66) и для аргумента k - ключевое значение 2? Я новичок в программировании и не понимаю, как по модулю работает в этом. Я знаю, что это берет значение остатка, но тогда не упростится ли это так?
c = B = 66
k = 2
I imagine the result should be 'D'
(66 - 65 +2)%26 +65
(3)%26 +65
0 + 65
65 = 'A'
Я не должен понимать, как работает%.
4 ответа
Ключевой факт - ASCII-код буквы "А" - 65.
Вот как работает ваш шифр - оригинальное выражение в заголовке вопроса.
- Возьмите ASCII-значение буквы, вычтите из него значение "A", и вы получите число, основанное на 0.
- Добавьте значение ключа к этому числу, сдвинув его на
k
мест. - Теперь разделите число, которое вы получили выше, на 26, отбросьте частное и используйте остаток. Это оператор по модулю
%
, Это всегда держит ваши числа в диапазоне 0-25, так как деление на 26 никогда не будет иметь остаток больше 25. - Добавьте 65 к нему, чтобы преобразовать его в "зашифрованную" заглавную букву.
Это позволяет ключу иметь ЛЮБОЙ номер и все еще сохраняет "зашифрованный" вывод в диапазоне ASCII AZ.
Вы интерпретируете %
Оператор как подразделение. На самом деле это оператор по модулю или забываю частное, я хочу остатка.
пример
0%2
это 01%2
это 12%2
это 03%2
это 1
И так далее. По модулю циклично.
Модуль не является внутренним делением. Модуль дает вам остаток от деления, поэтому 3 / 26 равен 0 с остатком 3. Следовательно, 3 % 26 равен 3.
3 % 26 - это 3, а не 0. Модуль - это остаток. Подумайте о модуле 12 на часах. Если это десять часов, и вы добавляете 4 часа, 10 + 4 = 14. Но на часах стрелка теперь указывает на 2, а не на 14. Независимо от того, сколько часов вы добавляете, стрелка всегда указывает на число от 1 до 12. Так работает модуль.
10 + 4 = 14
14% 12 = 2 (14, деленное на 12 - 1 с остатком 2)
10 + 100 = 110
110% 12 = 4 (110, деленное на 12 - остаток 4)
Если это 10 часов, а вы ждете 100 часов, стрелка теперь указывает на 4.
(Используя остаток от деления, деление на 12 всегда дает число от 0 до 11, так что думайте о 12 часах как о 0 часах.)
((c - 65 + k) % 26) + 65)
работает, но не переносим и излишне запутан.
это код ASCII символьной константы, представляющей букву .c - 65
или лучшеc - 'A'
оценивается как расстояние до заглавной буквы, хранящейся вc
отA
, следовательно1
для письмаB
.
Сложение приводит к сдвигу в алфавите, но может привести к смещению больше 25, следовательно, операция по модулю для вычисления остатка от деления на26
.(c - 65 + k) % 26
дает смещение, если закодированная буква.
Добавление65
или более уместно'A'
преобразует смещение обратно в заглавную букву.
Это выражение делает молчаливое предположение, что все заглавные буквы идут подряд в наборе символов выполнения, что верно для ASCII, но не для более старых наборов символов, таких какEBCDIC
.
Обратите также внимание, что приведенные выше выражения работают только для положительных значений . Если отрицательный результат(c - 'a' + k) % 26 + 'a'
может быть и отрицательным, поэтомуk
следует сначала изменить на положительное значение с помощью этого кода:
k = k % 26;
if (k < 0)
k = k + 26;
Вот более читаемая альтернатива:
char encode_letter(char c, int k) {
k = k % 26;
if (k < 0)
k = k + 26;
if (c >= 'A' && c <= 'Z')
return (c - 'A' + k) % 26 + 'A';
else
if (c >= 'a' && c <= 'a')
return (c - 'a' + k) % 26 + 'a';
else
return c;
}