Добрый день, уважаемые пользователи.
Сегодня я хотел бы рассказать про одну замечательную серию игр. Многие познакомились с ней, благодаря версии на NES, некоторые видели персидского принца на DOS, кто-то играл в Принц Персии на Sega Genesis и… вроде всё, но нет! Первая часть была портирована на большое количество разных игровых платформ. А сколько систем паролей было придумано по этому поводу? А сколько портов было у второй части? А какие пароли были там?
Про это я и хотел бы Вам рассказать.

Prince of Persia (Sega Master System/Sega Game Gear)


image

Теория


Пароль состоит из 6 позиций. Эти позиции сохраняют данные игровые параметры:
  • уровень (1-14)
  • время (0-99)
  • жизни (0-7)
  • рандом (0-25)

Генерация

1 позиция = ((уровень -1) + рандом) mod26
2 позиция = ((время div10) + рандом) mod26
3 позиция = ((время mod10) + рандом) mod26
4 позиция = (жизни + рандом) mod26
5 позиция = рандом
6 позиция = ((сумма позиций с 1 по 5) + 10) mod26

Кодирование

Символы в позициях принимают значения «ABCDEFGHIJKLMNOPQRSTUVWXYZ», где A=0, B=1… Y=24, Z=25.

Пример генерации пароля
Создадим пароль, который сохраняет данные параметры:
  • уровень (12)
  • жизни (6)
  • время (59)
  • рандом (18)

Вычисляем:
1)
1 позиция = ((12 -1) + 18) mod26
2 позиция = ((59 div10) + 18) mod26
3 позиция = ((59 mod10) +18) mod26
4 позиция = (6+18) mod26
5 позиция = 18
6 позиция = 10

2)
1 позиция = 3
2 позиция = 23
3 позиция = 1
4 позиция = 24
5 позиция = 18
6 позиция = (3+23+1+24+18+10) mod26 = 1

Теперь кодируем получившиеся значения:
DXBYSB

Интересный баг


В игре есть баг, с помощью которого можно получить бессмертие. Но перед объяснением, я хотел бы обсудить архитектуру уровней. Условно разделим экран на 3 этажа.

Этажи
image

Если у принца жизни от 1 до 7, то при падении со 2 этажа на 1, жизни не тратятся. А при падении с 3 этажа на 1, тратится 1 жизнь. Если жизней 0, то происходит всё наоборот. При падении со 2 этажа на 1, принц умирает, а при падении с 3 этажа на 1, происходит баг: игра даст принцу 8 жизней (не забываем, что максимум равняется семи).

8 жизней
image

После проделанной операции, принц сможет спрыгивать с 3 и 2 этажа, не нанося себе урон (если взять 4 этаж, то принц умрёт). Также принц будет неуязвим для вражеских атак (если оружие будет в руках). После прохождения уровня, баг исчезает и у принца снова станет 0 жизней. А если с нулём жизней напасть на стражника, то он Вас просто проигнорирует и убить его станет невозможно.

Принц-призрак
image

Вот так вот.

  

Prince of Persia (Game Boy/Game Boy Color)


image

Теория


Пароль состоит из 8 позиций. Эти позиции сохраняют данные игровые параметры:
  • уровень (2-14)
  • время (1-59)
  • жизни (3-9)

Примечание: на 7 уровень нельзя создать пароль.

Генерация

1 позиция = (4 позиция + 7 позиция + 8 позиция) mod10
2 позиция = (5 позиция + 6 позиция) mod10
3 позиция = (7 позиция + 8 позиция) mod10
4 позиция = жизни
5 позиция = время mod10
6 позиция = время div10
7 позиция = уровень mod10
8 позиция = уровень div10

Кодирование

Ко всем позициям применяется операция: XOR 5. Если после выполнения этой операции получилось двухзначное число, то надо вычесть 4.

Пример генерации пароля
Создадим пароль, который сохраняет данные параметры:
  • уровень (9)
  • жизни (7)
  • время (35)

Вычисляем:
1)
1 позиция = 0
2 позиция = 0
3 позиция = 0
4 позиция = 7
5 позиция = 35 mod10
6 позиция = 35 div10
7 позиция = 9 mod10
8 позиция = 9 div10

2)
1 позиция = (7+9+0) mod10 = 6
2 позиция = (5+3) mod10 = 8
3 позиция = (9+0) mod10 = 9
4 позиция = 7
5 позиция = 5
6 позиция = 3
7 позиция = 9
8 позиция = 0

Теперь кодируем получившиеся значения:
6 XOR 5 = 3
8 XOR 5 = 13-4 = 9
9 XOR 5 = 12-4 = 8
7 XOR 5 = 2
5 XOR 5 = 0
3 XOR 5 = 6
9 XOR 5 = 12-4 = 8
0 XOR 5 = 5

Готовый пароль: 39820685

  
  

Prince of Persia (Sega Genesis)


image

Теория


Пароль состоит из 6 позиций. Эти позиции сохраняют данные игровые параметры:

US version:
  • уровень (1-13)
  • время (0-60)
  • жизни (1-8)

EU version:
  • уровень (1-13)
  • время (0-60)
  • жизни (0-8)

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

Генерация

Условно разделим пароль на две части (каждая часть состоит из трёх позиций).

Первая часть сохраняет время:
(10545*время)mod 17576

Полученное число из 10 CC переводится в 26 СС (СС — система счисления).
Потом полученное значение нужно зеркально отобразить. Если длина полученного «пароля» меньше 3 символов, то справа дописывается необходимое число нулей.

Вторая часть сохраняет время, количество жизней и уровень:
((10545*время) + (14157*(уровень-1)) + (5145*жизни))mod 17576

Полученное число из 10 CC переводится в 26 СС. Потом полученное значение нужно зеркально отобразить. Если длина полученного «пароля» меньше 3 символов, то справа дописывается необходимое число нулей.

Кодирование

Символы в позициях принимают значения «ABCDEFGHIJKLMNOPQRSTUVWXYZ», где A=0, B=1… Y=24, Z=25.

Пример генерации пароля
Создадим пароль, который сохраняет данные параметры:
  • уровень (12)
  • жизни (6)
  • время (39)

Вычисляем:

Первая часть пароля:
(10545*39)mod 17576 = 411255 mod 17576 = 7007
7007 (10 СС) = 10,9,13 (26 СС)
Зеркально отображаем полученное значение:
10,9,13 =13,9,10

Вторая часть пароля:
((10545*39) + (14157*(12-1)) + (5145*6))mod 17576 = (411255+155727+30870)mod 17576 = 268
268 (10 СС) = 10,8 (26 СС)
Зеркально отображаем полученное значение:
10,8 = 8,10
Дописываем справа ноль:
8,10,0

Теперь кодируем получившиеся значения:
13,9,10,8,10,0 = NJKIKA

Интересный баг


В игре есть баг, с помощью которого можно получить бессмертие. Чтобы его активировать, нужно в EU версии ввести пароль с нулевым количеством жизней. Теперь принцу не страшны враги (главное — не убирать оружие). Но с активацией бага, игрок получает одну проблему. Если упасть с большой высоты, которая грозит потерей всех жизней, то ничего не произойдёт. Но если упасть с высоты, при которой у принца должна потратиться жизнь, то игра зависнет, а экран окрасится в красные тона.

 

Prince of Persia (SNES)


image

Вот и настало время поговорить о самой лучшей реализации первого персидского принца (по моему скромному мнению).

По сравнению со всеми предыдущими версиями, для SNES сделали более красочные локации, улучшили парирование, частично изменили начальные уровни и добавили много новых стадий (итого 20). А чтобы игрок не мучался, время увеличили до 120 минут (играй сколько влезет).

Теория


Пароль состоит из 7 позиций, каждая позиция состоит из 5 битов, итого 7*5= 35 битов. Эти биты сохраняют данные игровые параметры:
  • уровень (1-20)
  • затраченное на игру время (0-7200) (в секундах)
  • жизни (0-15)

Теперь посмотрим из чего состоит сырой пароль:

(?(0),S(0),L(3),T(0),T(7))   (C1(0),S(1),L(2),T(1),T(6))   (C2(0),S(2),L(1),T(2),T(5))   (C3(0),S(3),L(0),T(3),T(4))  

(C4(0),S(4),U(0),T(8),T(9))   (C4(1),T(10),T(11),T(12),T(13))  (C4(2),C4(3),C4(4),T(14),T(15))

* в скобках указан номер бита.

Обозначения

S — номер уровня ((1-20)-1) в двоичной C.C.
L — количество жизней (0-15) в двоичной C.C.
U — неиспользуемые биты.
? — всегда равен нулю.
T — затраченное на игру время (0-7200).
Время записывается в пароле, в соответствии со специальной формулой:

(время*7) + (5, если время mod60?0) + (5*((время div60)-1)) + рандом (0-6 + ((5, если время mod60=0) или (14534, если время div 7200=1)))

C1 = S(1) XOR S(4) XOR L(0) XOR L(1) XOR T(0) XOR T(1) XOR T(2) XOR T(5) XOR T(7) XOR T(8) XOR T(10) XOR T(13) XOR T(15) XOR U(0) XOR 1

C2 = S(1) XOR S(2) XOR S(3) XOR L(0) XOR L(2) XOR L(3) XOR T(1) XOR T(4) XOR T(5) XOR T(8) XOR T(9) XOR T(10) XOR T(12) XOR T(14) XOR T(15)

C3 = S(0) XOR S(1) XOR S(3) XOR L(2) XOR T(2) XOR T(3) XOR T(5) XOR T(6) XOR T(7) XOR T(8) XOR T(9) XOR T(11) XOR T(14) XOR U(0)

C4 = S(0),L(3),T(0),T(7)
     + S(1),L(2),T(1),T(6)
     + S(2),L(1),T(2),T(5)
     + S(3),L(0),T(3),T(4)
     + S(4),U(0),T(8),T(9)
   +T(10),T(11),T(12),T(13)
   +      0,      0,T(14),T(15)

Кодирование

US/EU: «BTL3GY7Q9CVM4HZ8R+DWN5J12S!FXP6K».
JP: «AIQYEMU34BJRZFNVW5CKS1GOPX6DLT2H».

Пример генерации пароля
Создадим пароль, который сохраняет данные параметры:
  • уровень (15)
  • жизни (13)
  • время (95.00) или (5700 секунд)
  • неиспользуемый бит активирован

Переводим значения в двоичную систему счисления:
Уровень = 15-1 =14 = 01110
Жизни = 13 = 1101

Вычисляем время:
Время = 7200-5700=1500
(1500*7) + (0, т.к. 1500 mod 60 = 0) + (5*(25-1)) + рандом (т.к. 1500 mod 60 = 0, то рандом = 0-6+5 = 0-11. Я выбираю рандом = 11.)
10500 + 120 + 11 = 10631 = 0010100110000111

Вычисляем контрольные суммы:
C1 = 1 XOR 0 XOR 1 XOR 0 XOR 1 XOR 1 XOR 1 XOR 0 XOR 1 XOR 1 XOR 0 XOR 1 XOR 0 XOR 1 XOR 1 = 0
C2 = 1 XOR 1 XOR 1 XOR 1 XOR 1 XOR 1 XOR 1 XOR 0 XOR 0 XOR 1 XOR 0 XOR 0 XOR 0 XOR 0 XOR 0 = 0
C3 = 0 XOR 1 XOR 1 XOR 1 XOR 1 XOR 0 XOR 0 XOR 0 XOR 1 XOR 1 XOR 0 XOR 1 XOR 0 XOR 1 = 0
C4 = 0111 + 1110 + 1010 + 1100 + 0110 +0101 + 0000 = 110110

Записываем получившийся пароль в двоичной С.С.:
(00111) (01110) (01010) (01100) (00110) (10101) (10100)

Записываем получившийся пароль в десятичной С.С.:
(7) (14) (10) (12) (6) (21) (20)

Теперь кодируем получившиеся значения:
US/EU: QZV475N
JP: 3NJZU1S

  
  

Prince of Persia 2: The Shadow & The Flame


Первая часть обрела огромную популярность. Выход сиквела был лишь вопросом времени. И через четыре года появилось продолжение. Но новая часть не сыскала бурных аплодисментов, которыми наградили первую часть. И портировали её на небольшое количество игровых платформ. А жаль! Я считаю, что вторая часть получилась лучше первой. Теперь принц путешествует не по однообразным тёмным локациям, а по целой Персии. Но хватит лирики, пора переходить к делу.

Игра обзавелась двумя портами, которые сохраняют игровой процесс с помощью паролей. Эти порты ужасны (лучше играйте в DOS версию). SNES версия получилась корявая: музыка дребезжащая, звуки противные, геймплей убит и ко всему этому, в игре вырезан 14 уровень, в котором должна состояться битва с Джаффаром.

Версия для Sega Genesis не лучше. Так как эту игру официально не выпустили, то я её смог увидеть только с помощью пиратского картриджа на Сегу. И каково? оказалось моё разочарование, когда я дошёл до 9 уровня и узнал, что из-за бага со статуей лошади, этот уровень непроходим. Игру можно пройти, но для этого нужен пароль на 10 уровень… а в книге паролей, этой игры не было.

  

Prince of Persia 2: The Shadow & The Flame (SNES)


image

Теория


Пароль состоит из 6 позиций, каждая позиция состоит из 4 битов, итого 6*4= 24 бита. Эти биты сохраняют данные игровые параметры:

US/EU versions:
  • уровень (1-13)
  • время (0-164)
  • жизни (1-15)

Теперь посмотрим из чего состоит сырой пароль:

(S(3),S(2),S(1),S(0))   (L(3),L(2),L(1),L(0))   (T1(3),T1(2),T1(1),T1(0))   (T2(3),T2(2),T2(1),T2(0))
 
(C1(3),C1(2),C1(1),C1(0))   (C2(3),C2(2),C2(1),C2(0))

Обозначения

S — (уровень — 1) в двоичной С.С.
L — количество жизней (1-15) в двоичной С.С.
T1 — 1 значение (0-15) в двоичной С.С.
T2 — 2 значение (0-15) в двоичной С.С.
1 значение — количество единиц времени (число десятков из 1 значения переходит во 2 значение).
2 значение — количество десятков времени (число десятков из 2 значения переходит в количество сотен).
C1 = (сумма позиций с 1 по 3) mod16
C2 = ((сумма позиций с 1 по 3) div16) + 4 позиция

Кодирование

Символы в позициях принимают значения «BCDFGHJKLMNPRTVW», где B=0… W=15.

Особенности сохранения времени и работоспособности пароля:

Если подумать, то всё просто — одна позиция отвечает за время mod10, а другая за время div10 и максимальное количество времени равняется 99. Но не всё так просто. В пароле не проверяется максимальное значение единиц и десятков. Что это значит? В пароле можно установить количество десятков и единиц от 0 до 15. Если я создам пароль, где количество единиц равно 15, то единиц будет 5, а 1 перейдёт в количество десятков, анологично, если я создам пароль, где количество десятков равно 15, то десятков будет 5, а 1 перейдёт в количество сотен.

Получается, максимальное количество времени равняется:

  150
+015
   =
  165

Но выше, я уже описал, что максимальное значение = 164. А почему? Это происходит из-за контрольной суммы. Если С2?16, то пароль не будет работать. Этот аспект я объясню чуть позже, а сейчас перейдём к генерации пароля (чтобы понять дальнейшее повествование, я советую прочитать пример генерации пароля).

Пример генерации пароля
Создадим пароль, который сохраняет данные параметры:
  • уровень (2)
  • жизни (1)
  • время (163)

Переводим значения в двоичную систему счисления:

Уровень = 2-1 =1 = 0001
Жизни = 1= 0001

Вычисляем время:

163= 150+13
1 значение = 13 = 1101
2 значение = 15 = 1111

Записываем сырой пароль и вычисляем 2 контрольные суммы:

(0001) (0001) (1101) (1111) (****) (****)

C1 = 0001+0001+1101 = 1111
C2 = (0001+0001+1101)mod16 + 1111 = 0000 + 1111 = 1111

(0001) (0001) (1101) (1111) (1111) (1111)

Записываем получившийся пароль в десятичной С.С.:

(1) (1) (13) (15) (15) (15)

Теперь кодируем получившиеся значения:

CCTWWW

Итог


Я создал пароль CCTWWW. Если увеличить уровень на 1, то пароль не будет работать, т.к. C2 станет равна 16. Неработающий пароль будет иметь вид: DCTWBB. А теперь проверим игру «на вшивость». Второй уровень очень короткий, поэтому его можно пройти без потери времени. Если я пройду уровень, какой пароль выдаст мне игра?

Вдруг в системе паролей есть секрет, который я не раскрыл? А что если…

Пароль
image

… вот зараза. В игре не только геймплей ужасный, но и система паролей недоделанная.
   
  

Prince of Persia 2: The Shadow & The Flame (Sega Genesis)


image

Теория


Пароль состоит из 5 позиций. Эти позиции сохраняют данные игровые параметры:

  • уровень (1-14)
  • время (0-99)
  • жизни (1-12)

Генерация

1 позиция = (уровень) или (уровень (1-7) +15)
2 позиция = (время mod10) или (время mod10 + 10) или (время mod10 (0-2) + 20)
3 позиция = (1 позиция + 2 позиция + 4 позиция + 5 позиция) mod23
4 позиция = (время div10) или (время div10 + 10) или (время div10 (0-2) + 20)
5 позиция = (жизни -1) или (жизни (1-11) + 11)

Кодирование

Символы в позициях принимают значения «HFMGRANBPWTEIZVQDLYSKCX», где H=0, F=1… C=21, X=22.

Пример генерации пароля
Создадим пароль, который сохраняет данные параметры:
  • уровень (11)
  • жизни (10)
  • время (92)

Вычисляем:

Первый шаг:
1 позиция = уровень сохраняется по одной из двух формул. Так как уровень больше 7, то сохранить данные можно только по первой формуле (11).
2 позиция = время сохраняется по одной из трёх формул. 92 mod10 = 2. Это значение можно закодировать по любой формуле и я выбираю третью (2+20 = 22)
3 позиция = 0
4 позиция = время сохраняется по одной из трёх формул. 92 div10 = 9. Это значение можно закодировать только по первой и второй формуле, и я выбираю вторую (9+10 = 19)
5 позиция = жизни сохраняются по одной из двух формул. Это значение можно закодировать по любой формуле и я выбираю вторую (10+11 = 21).

Второй шаг:
1 позиция = 11
2 позиция = 22
3 позиция = (11 + 22 + 19 + 21)mod 23 = 4
4 позиция = 19
5 позиция = 21

Теперь кодируем получившиеся значения:
EXRSC

  

Заключение


Вот и подошёл список игр к концу. Ну что ж, удачи, спасибо за прочтение.
Поделиться с друзьями
-->

Комментарии (25)


  1. printerresetter
    05.10.2016 19:08
    -21

    Народу видно занятся нечем, разбирает всякую ерунду. Скажите, какая от этого польза?


    1. awlvita
      05.10.2016 19:25
      +5

      И не поспоришь. Как таковой пользы нет.


    1. kuber
      05.10.2016 20:56
      +8

      Вы просто слишком молоды. Я в свое время потратил большое количество времени, чтобы понять как генерируются пароли в данной игре. И еще больше времени потратил на её прохождение.


      1. printerresetter
        11.10.2016 20:01

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


    1. lookid
      06.10.2016 00:45
      +1

      Если брать конкретную задачу, то это похоже на генерацию hash-кода.


    1. pewpew
      06.10.2016 08:20
      +2

      Смотря кому. Если вам, то вероятно никакой.


  1. pchelintsev_an
    05.10.2016 23:50
    +2

    Одна из любимых игр. У меня вопрос. Как Вы узнали, что именно так генерируются пароли? Можно ли привести ссылки на ресурсы, где более подробно разбирается генератор на основе реверс-инжиниринга игры? Очень хочется вкусить ассемблер любимой игры.


    1. awlvita
      06.10.2016 13:52

      Я это узнал, используя метод брутфорса паролей.


  1. LoadRunner
    06.10.2016 08:25

    Пример генерации паролей — это хорошо. Но почему нет примера расшифровки пароля?
    Особенно интересно для случаев, где надо выбирать одну из нескольких формул. Коллизий не будет?


    1. awlvita
      06.10.2016 16:25

      Коллизий не будет, если правильно составить алгоритм дешифрации.

      Но почему нет примера расшифровки пароля?

      Я не вижу в этом смысл. Хотя, весьма интересно найти каракули в блокнотике и понять: «А какие данные сохраняет этот пароль?»


      1. LoadRunner
        06.10.2016 17:19

        Ну я вижу в этом смысл, как демонстрацию того, что алгоритм генерации паролей работает в обе стороны, а не как в архиваторе Бабушкина.


        1. awlvita
          06.10.2016 18:01

          Если алгоритм работает в одну сторону, то должен работать и в обратную. Или я ошибаюсь?


          1. LoadRunner
            06.10.2016 20:46

            Зависит от алгоритма. Но суть в другом — в демонстрации, как он работает именно в обратную сторону. Как он из набора символов интерпретируется в жизни-время-уровень. Это ведь тоже интересный момент в генерации паролей.


            1. awlvita
              06.10.2016 21:09

              Если я ещё буду писать на Хабрахабре, то учту Ваше замечание.


  1. pchelintsev_an
    06.10.2016 18:11

    А ещё секреты в игре есть?


    1. awlvita
      06.10.2016 18:16

      В какой именно версии?


      1. Miay
        26.01.2017 21:29

        Переболел я уже соц. сетями, но тут появился телеграмм, который полностью дублирует любую соц. сеть :(


        1. awlvita
          06.10.2016 19:32

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


          1. pchelintsev_an
            06.10.2016 19:38

            Можете привести чит-коды? Я, по-моему, знаю один — Ctrl+L.


            1. awlvita
              06.10.2016 19:50

              Про чит-коды, Вы можете прочитать здесь.


          1. zamboga
            09.10.2016 09:39

            Есть ещё способ прохождения 1го уровня за 1 минуту, не бегая за мечом и не сражаясь со стражником.

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

            Меч при этом все равно появится автоматически во втором уровне=)


            1. pchelintsev_an
              09.10.2016 15:07

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


  1. pchelintsev_an
    06.10.2016 20:27
    +1

    Обзор исходного кода Prince of Persia для Apple II (три статьи):
    Часть 1 (введение)
    Часть 2 (загрузчик)
    Часть 3 (объяснение кода)

    Техническая дока от разработчика
    Ссылка на сырцы (на ассемблере)


  1. claymen
    09.10.2016 16:20
    +2

    Как раз на днях рассказывал напарнику, как в детстве летом у бабушки в деревне по вечерам на ч/б телике играли в приставку, в частности в принца, и что были коды и что я пытался их вычислять, путем сравнения нескольких кодов, так например мне удалось сделать код на первый уровень но с увеличенным временем на 150%.
    Надо заметить что было это ещё до школьного курса программирования, и никакх познаний, особенно битовых сдвигах и кодах символов небыло…
    Всё так принц персии шедевр.
    На ютубе есть ролик с рассказом как делалась игра, движения персонажа снимали на камеру, процесс переноса не вспомню, но поэтому он движется так правильно.


    1. pchelintsev_an
      09.10.2016 17:51

      Вот ролик