Verbesserungsvorschläge

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Hallo,
ich schreibe gerade an einem Malbolge Interpreter. Dort gibts eine Funktion crz die als Argument 2 Zahlen bekommt die über ein zweidimensionales Codebuch ziffernweise verarbeitet werden. Malbolge rechnet intern mit Zahlen der Basis 3, MAX_DIGITS ist dabei 10.

Mein bisheriger Ansatz sieht nicht besonders toll aus, deshalb bitte ich um Verbesserungsvorschläge.

Code: Alles auswählen

def crz(self, first_number, second_number):
        crypt_table = (("1", "0", "0"),
                            ("1", "0", "2"),
                            ("2", "2", "1"))
        crypted_value = []
        values1 = map(int, list(self.int_to_base3_str(first_number)))
        values2 = map(int, list(self.int_to_base3_str(second_number)))
        for index in xrange(Malbolge.MAX_DIGITS):
            crypted_value.append(crypt_table[values1[index]][values2[index]])
        return int("".join(crypted_value), Malbolge.BASE)
       
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo darktrym,
- die »list« sind überflüssig
- über »values1« und »values2« solltest Du mittels »zip« iterieren
- »int_to_base3_str« gibt hoffentlich immer Strings der Länge MAX_DIGITS zurück??
- warum ist »crz« eine Klassenmethode, da »self« genauso wie in »int_to_base3_str« gar nicht benutzt wird.

Code: Alles auswählen

CRYPT_TABLE = ((1,0,0), (1,0,2), (2,2,1))
def crz(first, second):
    B = Malbolge.BASE
    return reduce(lambda a,b: a*B+b, (
        CRYPT_TABLE[first/(B**n)%B][second/(B**n)%B]
            for n in range(Malbolge.MAX_DIGITS-1,-1,-1)))
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Vielen Dank.
Den Reduce Kram hab' ich noch nicht verstanden, dass braucht noch etwas Zeit.
Und da irgendwo noch ein anderer Fehler ist, der mein Interpreter nach den ersten Buchstaben vom Hello World crashen lässt bleibe ich vorerst bei meiner verbesserten Variante, die deutlich lesbarer ist.

Code: Alles auswählen

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(Malbolge.int_to_base3_str(number))))
        number = 0
        for index, pair in enumerate(zip(digits[0], digits[1])):
            number += Malbolge.BASE**(Malbolge.MAX_DIGITS - 1 - index) * CRYPT_TABLE[pair[0]][pair[1]]
        return number
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

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")
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Antworten