Globale Variablen - Variable nicht gefunden

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
Hosenschlange
User
Beiträge: 2
Registriert: Freitag 26. September 2014, 14:27

Moin,

in meinem Neulings-Wahnsinn habe ich versucht, die ISAAC Cipher von Pascal nach Python zu portieren. Hier gibts den Quelltext:

Code: Alles auswählen

#
#!/usr/bin/python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- 
#
#
# ISAAC Cipher
#
# rewritten from Pascal, taken from rosettacode.org
#

import os, sys

imode = ['iencrypt', 'idecrypt']
# global variables (task)
msg = 'a TopSecret secret'
key = 'this is my secret key'
xctx = ''			# XOR ciphertext
mctx = ''			# MOD ciphertext
xptx = ''			# XOR decryption plaintext
mptx = ''			# MOD decryption plaintext

# global variables (ISAAC)
# external
global randrsl
global randcnt
global mm
# internal
aa = bb = cc = 0

#
# procedures

def isaac():
    global mm
    cc += 1
    bb += cc
    i = 0
    while (i < 256):
        x = mm[i]
        if (i % 4) == 0:
            aa = aa ^ (aa << 13)
        elif (i % 4) == 1:
            aa = aa ^ (aa >> 6)
        elif (i % 4) == 2:
            aa = aa ^ (aa << 2)
        else:
            aa = aa ^ (aa >> 16)
        aa = mm[(i+128) % 256] + aa
        y = mm[(x>>2) % 256] + aa + bb
        mm[i] = y
        bb = mm[(y>>10) % 256] + x
        randrsl[i] = bb
        i += 1
    randcnt = 0

def mix(a, b, c, d, e, f, g, h):
    a = a ^ b << 11
    d += a
    b += c
    b = b ^ c >> 2
    e += b
    c += d
    c = c ^ d << 8
    f += c
    d += e
    d = d ^ e >> 16
    g += d
    e += f
    e = e ^ f << 10
    h += e
    f += g
    f = f ^ g >> 4
    a += f
    g += h
    g = g ^ h << 8
    b += g
    h += a
    h = h ^ a >> 9
    c += h
    a += b

def irandinit(flag):
    global mm
    aa = bb = cc = 0
    a = 0x9e3779b9
    b = c = d = e = f = g = h = a
    # scramble
    i = 0
    while (i < 4):
        mix(a,b,c,d,e,f,g,h)
        i += 1
    #
    i = 0
    while (i < 256):
        if (flag == True):
            a += randrsl[i+0]
            b += randrsl[i+1]
            c += randrsl[i+2]
            d += randrsl[i+3]
            e += randrsl[i+4]
            f += randrsl[i+5]
            g += randrsl[i+6]
            h += randrsl[i+7]
	#
        mix(a,b,c,d,e,f,g,h)
        mm[i+0] = a
        mm[i+1] = b
        mm[i+2] = c
        mm[i+3] = d
        mm[i+4] = e
        mm[i+5] = f
        mm[i+6] = g
        mm[i+7] = h
        i += 8
    #
    if (flag == True):
        i = 0
        while (i < 256):
            a += mm[i+0]
            b += mm[i+1]
            c += mm[i+2]
            d += mm[i+3]
            e += mm[i+4]
            f += mm[i+5]
            g += mm[i+6]
            h += mm[i+7]
            mix(a,b,c,d,e,f,g,h)
            mm[i+0] = a
            mm[i+1] = b
            mm[i+2] = c
            mm[i+3] = d
            mm[i+4] = e
            mm[i+5] = f
            mm[i+6] = g
            mm[i+7] = h
            i += 8
    #
    isaac()
    randcnt = 0

def iseed(seed, flag):
    global mm
    for i in range(256):
        mm[i] = 0
    m = len(seed) - 1
    for i in range(256):
        if (i > m):
            randrsl[i] = 0
        else:
            randrsl[i] = ord(seed[i+1])
    irandinit(flag)

def irandom():
    ret = randrsl[randcnt]
    randcnt += 1
    if (randcnt > 255):
        isaac()
        randcnt = 0
    return (ret and 0xffffffff)

def iranda():
    return ((irandom() % 95 + 32) and 0xff)

def ascii2hex(src):
    ret = ''
    l = len(src)
    ret += ord(s[i]).encode('hex')
    return ret

def vernam(msg):
    ret = ''
    for i in len(msg):
        ret += chr(iranda ^ ord(msg[i]))
    return ret

def letternum(letter, start):
    return ((ord(letter) - ord(start)) and 0xff)

def caesar(m, ch, shift, modulo, start):
    if (m == 'idecrypt'):
        shift = -shift
    n = letternum(ch, start) + shift
    n %= modulo
    if (n < 0):
        n += modulo
    return chr(ord(start) + n)

def vignere(msg, m):
    ret = ''
    for i in len(msg):
        ret += caesar(m, msg[i], iranda, 95, ' ')
    return ret

def main():
    # seed ISAAC with key
    iseed(key, True)
    # set mode: encryption
    mode = iencrypt
    # xor (Vernam)
    xctx = vernam(msg)
    # mod (Vignere)
    mctx = vignere(msg, mode)
    # set mode: decryption
    mode = idecrypt
    #
    iseed(key, True)
    # xor (Vernam)
    xptx = vernam(xctx)
    # mod (Vignere)
    mptx = vignere(mctx, mode)
    # output
    print ('Message ... ' + msg)
    print ('Key ....... ' + key)
    print ('XOR enc ... ' + ascii2dec(xctx))
    print ('MOD enc ... ' + ascii2dec(mctx))
    print ('XOR dec ... ' + xptx)
    print ('MOD dec ... ' + mptx)

#
# main
print ('ISAAC Cipher')
# call main test procedure
main()

# end of program
Nur leider bekomme ich stets diesen Fehler:

Bild

Ich programmiere unter Mint 17 x64. Es ist egal, ob ich Python 2.7 oder 3.4 nehme. Der Fehler ist derselbe. Kann mir da jemand helfen?
BlackJack

@Hosenschlange: Wie die Fehlermeldung schon sagt: Der Name `mm` wird nicht definiert. ``global`` deklariert einen Namen nur als Global, sofern er irgendwann definiert wird/wurde, *und* ``global`` auf Modulebene hat keinen Effekt, macht dort also keinen Sinn.

Letztendlich sollte man ``global`` auch in Funktionen nicht verwenden. Wenn Du in einer Funktion ein Objekt modifizieren möchtest, dann übergib es als Argument.

Du hast bei der Übersetzung auch sehr 1:1 den Pascal-Quelltext in Python-Syntax umgesetzt wie es scheint, was zu einem nicht gerade idiomatischen Python-Quelltext führt.
Hosenschlange
User
Beiträge: 2
Registriert: Freitag 26. September 2014, 14:27

Das stimmt soweit, ich fange aber auch gerade erst an.
Wie kann ich den Fehler auflösen, so dass das Programm macht, was ich eigentlich vorhabe?
BlackJack

@Hosenschlange: Sagte ich doch schon: der Funktion ein geeignetes `mm` als Argument übergeben.

Alternativ: Nicht den Quelltext 1:1 übertragen sondern eine Lösung in Python programmieren.
Antworten