Seite 1 von 1

Globale Variablen - Variable nicht gefunden

Verfasst: Freitag 26. September 2014, 14:41
von Hosenschlange
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?

Re: Globale Variablen - Variable nicht gefunden

Verfasst: Freitag 26. September 2014, 15:17
von 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.

Re: Globale Variablen - Variable nicht gefunden

Verfasst: Freitag 26. September 2014, 15:41
von Hosenschlange
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?

Re: Globale Variablen - Variable nicht gefunden

Verfasst: Freitag 26. September 2014, 15:47
von 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.