[SMD] Spot Goes to Hollywood: генератор паролей

Jan 05, 2020 02:42

Ещё в старом году сваял генератор паролей на Spot Goes to Hollywood, но руки не дошли до публикации.
Используется классическое для сеги 5 битовое кодирование символов и алфавит

ABCDEFGHIJKLMNOPQRSTUVWXYZ345678

Пароль из 8 символов что даёт 40 битов. Битовая структура пароля:

AAAABBBB CCCCDDDD EFFFFGHH JJJJJJKK LLLLLLLL

A - сотни тысяч очков (0-9, если >9 то невалидный пароль)
B - десятки тысяч очков (0-9, если >9 то невалидный пароль)
С - тысячи очков (0-9, если >9 то невалидный пароль)
D - сотни очков (0-9, если >9 то невалидный пароль)
E - если установлен, то +50 очков
F - флаги пройденности этапов мира слева направо. 4й флаг актуален только для последнего мира, т.к. там 4 этапа. Если для любого мира, кроме последнего, выставить все 3 этапа пройденными, то продолжить игру с такого пароля не получится, ни один из пройденных этапов нельзя будет выбрать на экране выбора. Пароль последнего мира с пройденными 4мя этапами даст финальный уровень Complex.
G - флаг пройденности 1го этапа следующего мира (баг, если установить этот бит и пройти текущий мир, то на следуюшем мире первый уровень окажется пройденным - такого не может быть при нормальной игре)
H - мир: 00 - корабль, 01 - дом/замок, 10 - храм, 11 - будущее/космос
J - количество жизней от 0 до 63
K - сложность: 00 - easy, 01 - normal, 10 - hard, 11 - даст невалидный пароль
L - контрольная сумма

Алгоритм шифрования:

Весь пароль как видно составляет 5 байт. Берём 1й (считая с 0) байт, т.е. CCCCDDDD и используем его в качестве ключа:

1) 0й байт (AAAABBBB) XORим с ключом (т.е. c 1м байтом CCCCDDDD), сохраняем результат в 0й байт
2) 1й байт оставляем без изменений, чтобы декодирующий алгоритм мог взять ключ и расшифровать им пароль
3) меняем ключ - инвертируем все биты ключа (эквивалентно XOR с 0xFF)
4) 2й байт XOR'им с текущим ключом, результат записываем во 2й байт
5) меняем ключ - сдвигаем все биты ключа влево на 1 разряд, оставляем от результата только 8 младших бит, т.е. вытолкнутый 9й бит забываем (экивалентно операции AND c 0xFF)
6) 3й байт XOR'им с полученным на предыдущем шаге ключом, результат сохраняем в 3й байт
7) берём все зашифрованные ранее байты (0-3) пароля как есть по порядку, составляем из них слово.
8) XORим слово из п.7 с константой 0x4C49434B, получаем окончательно зашифрованные байты пароля

Алгоритм контрольной суммы:
1) инициализируем контрольную сумму 0
2) берём 0й зашифрованный байт пароля, умножаем на 3, прибавляем к контрольной сумме
3) берём 1й зашифрованный байт пароля, умножаем на 2, прибавляем к контрольной сумме
4) берём 2й зашифрованный байт пароля, умножаем на 1, прибавляем к контрольной сумме
5) берём 3й зашифрованный байт пароля, умножаем на 0, прибавляем к контрольной сумме - epic fail разработчиков, байт с жизнями и сложностью не влияет на контрольную сумму - не защищён от модификации. Поэтому в интернете попадаются рекомендации - "для увеличения числа жизней замените 6й символ пароля на цифру"
6) берём полученное значение контрольной суммы по модулю 256 (эквивалентно AND 0xFF), это и будет последний 4й (счёт с 0) байт пароля.

Переводим полученные 5 байт (40 бит) пароля в алфавит - классически берём по 5 бит и используем как индекс в алфавите.

Пример ручной генерации пароля:

Сгенерируем пароль со следующими параметрами:

Количество очков: 123450
Мир: дом/замок
Пройденные этапы: самый правый (замок)
Количество жизней: 42
Сложность: normal

Запишем информационные биты:

Очки:
0001 0010 0011 0100 1
Этапы:
0010
Бажный бит:
0
Мир:
01
Жизни:
101010
Сложность:
01

Собираем все биты вместе и группируем по байтам, получаем нешифрованный пароль:

00010010 00110100 10010001 10101001

Ключ шифрования: 00110100
Шифруем 0й байт:
00010010 ^ 00110100 = 00100110
Меняем ключ: 00110100 -> 11001011
Шифруем 2й байт:
10010001 ^ 11001011 = 01011010
Меняем ключ: 11001011 -> 10010110
Шифруем 3й байт:
10101001 ^ 10010110 = 00111111

Собираем шифрованные байты в слово:
26345A3F
Шифруем константой:
26345A3F ^ 4C49434B = 6A7D1974

Считаем контрольную сумму:
(3*6A + 2*7D + 19) AND 0xFF = 51

Зашифрованный пароль: 6A7D197451
Переводим в биты:
01101010 01111101 00011001 01110100 01010001
Разбиваем на группы по 5 бит:
01101 01001 11110 10001 10010 11101 00010 10001
Или в числовой форме:
13, 9, 30, 17, 18, 29, 2, 17
Переводим в буквы используя алфавит:
NJ7RS6CR

passgens, sega, game

Previous post
Up