Cazafantasmas I...
Cazafantasmas I...
Lo que son las cosas, estaba ordenando unos libros y de uno de ellos cayó un folio doblado con una de esas miles de cosas que uno hace y luego termina olvidando hacerlas publicas. Así que para que no pase de nuevo y aprovechando ese 1% de actividad retro del que estoy gozando estos días
Se trata del primer juego de los Cazafantasmas, si queréis obtener el máximo de dinero, pues es solo usar mi cuenta bancaria , si es que uno es así de generoso
Basta solo introducir como nombre SYX y como número de cuenta el 46276631, y tendrás a tu disposición 999.900 $ con los que poder equipar tu equipo con todos los lujos, jejeje.
El algoritmo para generar los números de cuenta no tiene ningún misterio, pero si alguien tiene interés puedo poner un pequeño script en python ó explicar un poco como funciona.
Se trata del primer juego de los Cazafantasmas, si queréis obtener el máximo de dinero, pues es solo usar mi cuenta bancaria , si es que uno es así de generoso
Basta solo introducir como nombre SYX y como número de cuenta el 46276631, y tendrás a tu disposición 999.900 $ con los que poder equipar tu equipo con todos los lujos, jejeje.
El algoritmo para generar los números de cuenta no tiene ningún misterio, pero si alguien tiene interés puedo poner un pequeño script en python ó explicar un poco como funciona.
- deepfb
- Master of The Forum
- Mensajes: 1475
- Registrado: Vie 07 Oct , 2005 5:20 pm
- Ubicación: Madrid
- Contactar:
Re: Cazafantasmas I...
¡Friqui! xDDDLo que son las cosas, estaba ordenando unos libros y de uno de ellos cayó un folio doblado con una de esas miles de cosas que uno hace y luego termina olvidando hacerlas publicas.
- robcfg
- Master of The Forum
- Mensajes: 1311
- Registrado: Jue 03 Abr , 2008 5:32 pm
- Ubicación: Estocolmo
- Contactar:
Re: Cazafantasmas I...
¿Ahora te das cuenta?¡Friqui! xDDD
Voy a tener que volver a jugarme el juego, ¡por los loles!
- jgonza
- Keeper of The Forum
- Mensajes: 962
- Registrado: Mié 04 Abr , 2007 9:21 pm
- Ubicación: Alboraya (Valencia)
Re: Cazafantasmas I...
Pues vas a tener que explicarlo un poco porque si no parece que efectivamente estemos accediendo de forma remota a tu propia cuenta bancariaEl algoritmo para generar los números de cuenta no tiene ningún misterio, pero si alguien tiene interés puedo poner un pequeño script en python ó explicar un poco como funciona.
Visita mi canal de YouTube http://www.youtube.com/c/jgonza
Re: Cazafantasmas I...
Jajejijoju jajejijoju¿Ahora te das cuenta?¡Friqui! xDDDLo que son las cosas, estaba ordenando unos libros y de uno de ellos cayó un folio doblado con una de esas miles de cosas que uno hace y luego termina olvidando hacerlas publicas.
Es que yo soy así de desprendidoPues vas a tener que explicarlo un poco porque si no parece que efectivamente estemos accediendo de forma remota a tu propia cuenta bancariaEl algoritmo para generar los números de cuenta no tiene ningún misterio, pero si alguien tiene interés puedo poner un pequeño script en python ó explicar un poco como funciona.
De todas formas, si alguien me explica cuál es la idea de como debería ser una entrada para trucos dentro de la ficha de un juego en el flamante wiki del que disponemos ahora (¡Enhorabuena a los responsable! Así es como siempre debió ser ).
Es para poder mantener la estética y estilo del wiki; ya que he estado mirando algunas fichas que deberían tener códigos ó trucos (como After The War, AMC, ...) y no veo ningún apartado especial. Me imagino que debería ser ese "Extra", pero en todas las fichas que he visto con esa sección, son solo meros escaneos de las revistas.
Re: Cazafantasmas I...
¿Quién ha dicho que no? http://www.amstrad.es/doku.php?id=foraneos:ghostbustersDe todas formas, si alguien me explica cuál es la idea de como debería ser una entrada para trucos dentro de la ficha de un juego en el flamante wiki del que disponemos ahora (¡Enhorabuena a los responsable! Así es como siempre debió ser ).
Pues todos los trucos y demás son bienvenidos! En principio pueden colgarse aquí y los iríamos subiendo. No recuerdo en qué estado se encuentran ahora mismo las entradas colaborativas en el wiki, a ver si arta nos ilumina un poco...Es para poder mantener la estética y estilo del wiki; ya que he estado mirando algunas fichas que deberían tener códigos ó trucos (como After The War, AMC, ...) y no veo ningún apartado especial. Me imagino que debería ser ese "Extra", pero en todas las fichas que he visto con esa sección, son solo meros escaneos de las revistas.
Re: Cazafantasmas I...
No recuerdo en qué estado se encuentran ahora mismo las entradas colaborativas en el wiki, a ver si arta nos ilumina un poco...
Salu2,
Arta
Arta
- jgonza
- Keeper of The Forum
- Mensajes: 962
- Registrado: Mié 04 Abr , 2007 9:21 pm
- Ubicación: Alboraya (Valencia)
Re: Cazafantasmas I...
A esa entrada le falta la sección Amstrad TV correspondiente¿Quién ha dicho que no? http://www.amstrad.es/doku.php?id=foraneos:ghostbusters
Visita mi canal de YouTube http://www.youtube.com/c/jgonza
Re: Cazafantasmas I...
Perfecto Miguel, entonces vamos a explicar aquí con todo lujo de detalles "el truco del almendruco" (que es como mi viejo colega Faly diría, jejeje) del Cazafantasmas I.
Como en todo juego de la época, el método es más ingenioso que potente, y es que tampoco deberíamos esperar mucho de un "sistema de criptografía" de los 80, jejeje.
El juego hace uso de un nombre y un número de cuenta para acceder al dinero que esa cuenta tiene en depósito. Como podemos adivinar, es ese número de cuenta donde está realmente codificada la cantidad de dinero de que disponemos más un algo que es dependiente de ese nombre que dimos originalmente (es lo que sería la sal del algoritmo).
El nombre no es más que una cadena de caracteres con una longitud máxima de 20, si el nombre es mayor pues se recortan a 20 (aunque en realidad el juego no te deja introducir más de 20) y si es inferior, pues se rellenan el resto con espacios. Nota importante, aunque el relleno es con espacios, internamente todos los espacios de esa cadena son convertidos al carácter ']' y todos los caracteres alfabéticos son convertidos a mayúsculas.
En cuanto al dinero, el juego admite un máximo de 999.900$, aunque en realidad solo se usan los 4 primeros dígitos, los dos últimos siempre serán ceros. Así que voy a reemplazar esos dígitos importantes por ABCD, por lo que la cantidad sería ABC.D00$.
Ya con respecto al número de cuenta, ésta está constituida por 8 dígitos; y si es inferior a esos 8, se añaden ceros por la izquierda.
Ahora comienza la diversión, creamos un nombre así al azar, como 'Clodomiro es el mejo' y queremos que el muchacho tenga un saldo de 123400$. Si aplicamos el script en python, obtendremos que el número de cuenta resultante será la '15057422'.
Ok, ¿cómo llegamos a esa cuenta? Vamos a ir de atrás adelante, cogemos ese número de cuenta y es "intuitivo" (:P) que ese número está en octal. Así que vamos a convertir de octal a hexadecimal y '15057422' en hexadecimal es '345F12'. Curioso, ¿no?
¡Eso es! Parece que el dinero que queríamos está ahí, más exactamente parece que la cantidad de dinero se codifica como CDxxAB, y con respecto a ese xx tan raro, no es más que una suma de comprobación, la cual sirve para garantizar que es un número de cuenta válida para el nombre que introducimos originalmente.
Para poder generar ese xx, se usa el siguiente algoritmo (parece que se destroza toda la tabulación, por eso lo he añadido en un zip adjunto):
Como podemos ver, es una traducción directa del código de z80 a python; hay un valor al que he llamado feedback el cual se duplica y se hace un XOR con el checksum actual. Ese bucle se repite una serie de veces (do_times) y todos esos "& 255" son solos porque estamos trabajando con números de 8 bits (nuestro querido z80).
Por lo que solo nos falta saber dos valores, el primero es el número de veces que se repite ese bucle, el cual no no es más que sumar los valores ascii de los caracteres del nombre (módulo 255). Y el segundo es el valor inicial del feedback, el cual es la suma de AB y CD (modulo 255), y en el caso específico de que esa suma sea 0, pues vamos a reemplazar ese resultado por 1.
Y eso es todo, pego por aquí el script en python, si alguien quiere convertirlo a otro lenguaje, sin problemas, como si lo quieren portar a locomotive basic, jejeje (decididamente ha destrozado toda la tabulación, por lo que lo he adjuntado como zip, pero me ha metido como tres adjuntos, mi no compre pan )
Como en todo juego de la época, el método es más ingenioso que potente, y es que tampoco deberíamos esperar mucho de un "sistema de criptografía" de los 80, jejeje.
El juego hace uso de un nombre y un número de cuenta para acceder al dinero que esa cuenta tiene en depósito. Como podemos adivinar, es ese número de cuenta donde está realmente codificada la cantidad de dinero de que disponemos más un algo que es dependiente de ese nombre que dimos originalmente (es lo que sería la sal del algoritmo).
El nombre no es más que una cadena de caracteres con una longitud máxima de 20, si el nombre es mayor pues se recortan a 20 (aunque en realidad el juego no te deja introducir más de 20) y si es inferior, pues se rellenan el resto con espacios. Nota importante, aunque el relleno es con espacios, internamente todos los espacios de esa cadena son convertidos al carácter ']' y todos los caracteres alfabéticos son convertidos a mayúsculas.
En cuanto al dinero, el juego admite un máximo de 999.900$, aunque en realidad solo se usan los 4 primeros dígitos, los dos últimos siempre serán ceros. Así que voy a reemplazar esos dígitos importantes por ABCD, por lo que la cantidad sería ABC.D00$.
Ya con respecto al número de cuenta, ésta está constituida por 8 dígitos; y si es inferior a esos 8, se añaden ceros por la izquierda.
Ahora comienza la diversión, creamos un nombre así al azar, como 'Clodomiro es el mejo' y queremos que el muchacho tenga un saldo de 123400$. Si aplicamos el script en python, obtendremos que el número de cuenta resultante será la '15057422'.
Ok, ¿cómo llegamos a esa cuenta? Vamos a ir de atrás adelante, cogemos ese número de cuenta y es "intuitivo" (:P) que ese número está en octal. Así que vamos a convertir de octal a hexadecimal y '15057422' en hexadecimal es '345F12'. Curioso, ¿no?
¡Eso es! Parece que el dinero que queríamos está ahí, más exactamente parece que la cantidad de dinero se codifica como CDxxAB, y con respecto a ese xx tan raro, no es más que una suma de comprobación, la cual sirve para garantizar que es un número de cuenta válida para el nombre que introducimos originalmente.
Para poder generar ese xx, se usa el siguiente algoritmo (parece que se destroza toda la tabulación, por eso lo he añadido en un zip adjunto):
Código: Seleccionar todo
checksum = 0
for i in range(do_times):
checksum = feedback # LD C,A ; Upper + Middle
feedback = ((feedback * 2) & 255) ^ checksum # SLA A ; (A * 2) & 255
# XOR C ; A ^ C | Carry = 0
feedback = ((feedback * 2) & 255) ^ checksum # SLA A ; (A * 2) & 255
# XOR C ; A ^ C | Carry = 0
feedback = ((feedback * 4) & 255) ^ checksum # SLA A ; (A * 2) & 255
# SLA A ; (A * 2) & 255
# XOR C ; A ^ C | Carry = 0
checksum = (((checksum * 2) + 1) & 255) if (feedback * 2 > 255) else ((checksum * 2) & 255) # SLA A ; (A * 2) & 255
# RL C ; C * 2 + Carry
feedback = checksum # LD A,C ; A = C
Por lo que solo nos falta saber dos valores, el primero es el número de veces que se repite ese bucle, el cual no no es más que sumar los valores ascii de los caracteres del nombre (módulo 255). Y el segundo es el valor inicial del feedback, el cual es la suma de AB y CD (modulo 255), y en el caso específico de que esa suma sea 0, pues vamos a reemplazar ese resultado por 1.
Y eso es todo, pego por aquí el script en python, si alguien quiere convertirlo a otro lenguaje, sin problemas, como si lo quieren portar a locomotive basic, jejeje (decididamente ha destrozado toda la tabulación, por lo que lo he adjuntado como zip, pero me ha metido como tres adjuntos, mi no compre pan )
Código: Seleccionar todo
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Ghostbusters Piggy bank
(c) SyX, 2018
"""
__version__ = '0.1'
import sys
def get_account_number(user_name, money_request):
"""
Generate a valid account number for Ghostbusters CPC
"""
# Get the first 4 digits of the balance as bytes, used for encoding the account number(XXYY00)
money_string = str(money_request // 100)
money_upper_byte = int(money_string[0]) * 16 + int(money_string[1])
money_middle_byte = int(money_string[2]) * 16 + int(money_string[3])
# Number of passes over the checksum calculation (sum of chars mod 256)
do_times = sum(ord(i) for i in user_name[:20]) & 255
# Value use for feedback
feedback = 1 if ((money_upper_byte + money_middle_byte) & 255) == 0 else ((money_upper_byte + money_middle_byte) & 255)
checksum = 0
for i in range(do_times):
checksum = feedback # LD C,A ; Upper + Middle
feedback = ((feedback * 2) & 255) ^ checksum # SLA A ; (A * 2) & 255
# XOR C ; A ^ C | Carry = 0
feedback = ((feedback * 2) & 255) ^ checksum # SLA A ; (A * 2) & 255
# XOR C ; A ^ C | Carry = 0
feedback = ((feedback * 4) & 255) ^ checksum # SLA A ; (A * 2) & 255
# SLA A ; (A * 2) & 255
# XOR C ; A ^ C | Carry = 0
checksum = (((checksum * 2) + 1) & 255) if (feedback * 2 > 255) else ((checksum * 2) & 255) # SLA A ; (A * 2) & 255
# RL C ; C * 2 + Carry
feedback = checksum # LD A,C ; A = C
account_code = '{:o}'.format(money_middle_byte * 256 * 256 + checksum * 256 + money_upper_byte)
account_code = account_code[:8] if len(account_code) >= 8 else account_code.rjust(8, '0')
return account_code
# Función principal
def main():
"""
Main function
"""
# Get a name
user_name = 'syx'
# And truncate it to the maximum size the game permits, padding with spaces
user_name = user_name.upper()
user_name = user_name[:20] if len(user_name) >= 20 else user_name.ljust(20, ' ')
user_name = user_name.replace(' ', ']') # CPC version replaces Spaces by ']'
# How much money do you want?
money_request = 1000000
money_request = 999900 if (money_request > 999900) else money_request
account_number = get_account_number(user_name, money_request)
print('Account: {} Client: {} Balance: {}'.format(account_number, user_name.replace(']', ' '), money_request))
return 0 # EXIT_SUCCESS
if __name__ == "__main__":
estado = main()
sys.exit(estado)
- Adjuntos
-
- ghostbusters.zip
- (1.12 KiB) Descargado 25 veces
-
- ghostbusters.zip
- (1.12 KiB) Descargado 17 veces
-
- ghostbusters.zip
- (1.12 KiB) Descargado 21 veces
Re: Cazafantasmas I...
Fantástico.
Cuando tenga unos días me siento a verlo, mientras entiendo por qué no me dediqué a esto.
Guau, que pasada y que buena explicación paso a paso.
Cuando tenga unos días me siento a verlo, mientras entiendo por qué no me dediqué a esto.
Guau, que pasada y que buena explicación paso a paso.
Re: Cazafantasmas I...
Prometo que no es tan complejo, la gracia ó mejor dicho, lo que me ahorró más tiempo en su día, fue el darme cuenta que los números de cuenta estaban en octal... pero cuando comienzas a ver unos cuantas cuentas, se aprecia rápidamente que nunca sale un número mayor que 7. Y aunque hoy en día están en desuso y prácticamente octales solo los vas a encontrar en los permisos de los ficheros en linux y bsd, entonces se usaba bastante y la mayoría de herramientas y lenguajes de programación daban soporte a ese sistema numérico.
El resto es lo normal en estos casos, el Z80 no ofrece casi nada para hacer operaciones matemáticas complejas, así que al final todo el mundo tira de XOR y las instrucciones de rotación y desplazamiento de bits (*). Por lo que una buena forma de encontrar estás rutinas de "codificación/encriptación/sumas de comprobación" es buscar por grupos de instrucciones de este tipo.
(*): Para que os hagáis una idea hasta el DAAD usa un simple XOR para codificar los textos y que no sean visibles con un simple volcado de la memoria... esa es una de las cosas que yo eliminé en esa versión mejorada del DAAD para CPC que mostré la última vez que estuve por allí arriba; en mi caso es para poder comprimir los textos de las localizaciones y así poder permitir aventuras más complejas, usando las descripciones largas de los 16 bits (y el PCW), así como dar soporte a los 128 KBs y la disquetera.
El resto es lo normal en estos casos, el Z80 no ofrece casi nada para hacer operaciones matemáticas complejas, así que al final todo el mundo tira de XOR y las instrucciones de rotación y desplazamiento de bits (*). Por lo que una buena forma de encontrar estás rutinas de "codificación/encriptación/sumas de comprobación" es buscar por grupos de instrucciones de este tipo.
(*): Para que os hagáis una idea hasta el DAAD usa un simple XOR para codificar los textos y que no sean visibles con un simple volcado de la memoria... esa es una de las cosas que yo eliminé en esa versión mejorada del DAAD para CPC que mostré la última vez que estuve por allí arriba; en mi caso es para poder comprimir los textos de las localizaciones y así poder permitir aventuras más complejas, usando las descripciones largas de los 16 bits (y el PCW), así como dar soporte a los 128 KBs y la disquetera.
Re: Cazafantasmas I...
Mi pregunta es: llegaste a esa conclusión por observación o destripando el código? Si es lo primero, eres hyperfriki
¿Quién está conectado?
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro
La Comunidad Española |