Hier ist nun der komplette Code, wenigstens das Hello World Beispiel scheint zu funktionieren.
Irgendwie gibt da einen math. Kniff, wie das Rotieren direkt mathematisch beschrieben werden kann.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
__author__ = "Daniel Ölschlegel"
__license__ = "bsdl"
__version__ = "0.01"
BASE = 3
MAX_DIGITS = 10
MAX_NUMBER = BASE**MAX_DIGITS
OPCODES = {"jmp":4, "out":5, "in":23, "mov":40, "rotr":39, "crz":62, "nop":68, "end":81}
def int_to_base3_str(number):
'''convert a positive integer number to a string which represents a number with the base of 3
the number is limited to MAX_NUMBER and a string is returned with a length of 10
'''
if number >= MAX_NUMBER:
raise ValueError
digits = ''
div, mod = divmod(number, BASE)
while div:
digits = str(mod) + digits
div, mod = divmod(div, BASE)
return "%s%d%s" % ((MAX_DIGITS - len(digits) - 1) * '0', mod, digits)
def encrypt(number):
'''uses a ecb mode for encryption'''
CRYPT_TABLE = '9m<.TVac`uY*MK\'X~xDl}REokN:#?G"i@5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72FhOA1CB6v^=I_0/8|jsb'
#print CRYPT_TABLE, len(CRYPT_TABLE)
return ord(CRYPT_TABLE[number % 94])
def crz(first, second):
CRYPT_TABLE = ((1, 0, 0),
(1, 0, 2),
(2, 2, 1))
crypted_value = []
digits = []
for number in (first, second):
digits.append(map(int, list(int_to_base3_str(number))))
number = 0
for index, pair in enumerate(zip(digits[0], digits[1])):
number += BASE**(MAX_DIGITS - 1 - index) * CRYPT_TABLE[pair[0]][pair[1]]
return number
def rotr(number):
'''rotate value of the given memory address
the last digits is the first, the rest is shifted to right'''
number = int_to_base3_str(number)
return int(number[-1] + number[:-1], BASE)
def run(source):
#reset all registers
a = c = d = 0
memory = []
#strip whitespaces and other invalid characer
for filter in (" ", "\n"):
source = source.replace(filter, "")
#copy the code into memory as numbers
memory = map(ord, source)
#encrypt the free space, by the way code should at least 2 bytes long
for index in xrange(len(source), MAX_NUMBER):
memory.append(crz(memory[index - 2], memory[index - 1]))
while True:
opcode = (memory[c] + c) % 94
if opcode in OPCODES.values():
if opcode == OPCODES["jmp"]:
c = memory[d]
elif opcode == OPCODES["out"]:
sys.stdout.write(chr(a % 256))
elif opcode == OPCODES["in"]:
try:
chars = raw_input("")
a = ord("\n") if not chars else ord(chars[0])
except EOFError:
a = MAX_NUMBER - 1
elif opcode == OPCODES["rotr"]:
a = memory[d] = rotr(memory[d])
elif opcode == OPCODES["mov"]:
d = memory[d]
elif opcode == OPCODES["crz"]:
a = memory[d] = crz(memory[d], a)
elif opcode == OPCODES["end"]:
break
elif opcode == OPCODES["nop"]:
pass
#encrypt current instruction
memory[c] = encrypt(memory[c])
c = (c + 1) % MAX_NUMBER
d = (d + 1) % MAX_NUMBER
if __name__ == '__main__':
run("(\'&%:9]!~}|z2Vxwv-,POqponl$Hjig%eB@@>a=<M:9[p6tsl1TS/QlOj)L(I&%$\"\"Z~AA@UZ=RvttT`R5P3m0LEDh,T*?(b&`$#87[}{W")