Verschlüsselung mit verschobenen Buchstaben

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
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Hi,

ich habe aus etwas Lust und Zeit heraus ein kleines Script geschrieben, dass einen Text, den man dem Script mitgibt, verschlüsselt und im selben Durchlauf auch wieder entschlüsselt (entspricht in etwas der Cäsar-Verschlüsselung).

Das Script generiert aus einem vordefinierten Alphabet (Buchstaben, Zahlen, Sonderzeichen) ein neues Alphabet in dem alle Zeichen durch eine Zufallsmethode durchgewüfelt werden (Ja, ich weiss, dass es nicht wirklich 100%ig zufällig ist, aber das sollte auch nur erstmal als Übung sein). Dann wird das neu generierte Alphabet um so viele Positionen geshiftet (also verschoben), wie man dem Aufrufer mitgibt.

Beide Alphabete dienen dann zur Ver- und Entschlüsselung des Originaltextes, indem die entsprechenden Positionen jedes einzelnen Buchstabens im geshifteten Alphabet durchsucht und durch den entsprechend neuen Buchstaben ersetzt werden.

Beim Entschlüsseln passiert das genau anders herum.

Na ja, ich weiss, das ist keine Verschlüsselung im Sinne heutiger Standards, aber als Übung machts mir Spass sowas zu entwickeln und damit zu spielen.

Was hättet Ihr in dieser ersten Rohversion anders/besser gemacht? (Es fehlen natürlich noch viele Sachen, auch entsprechende try-except Blöcke fehlen erstmal).


Hier das Script:

Code: Alles auswählen

#!c:\python26\python.exe
# -*- coding: utf-8 -*-

#@Author: ne0h
#@Date: 06.10.2008

""" This script implements some simple encryption/decryption.
 
An pre-defined alphabet  with various characters is randomized 
with the standard randint()-method and generates a new alphabet
each time the encryption is started. After that the alphabet 
is shifted as many positions are passed in. The text passed into the 
script gets encrypted and decrypted and the last method prints out 
the original text, the encrypted text and the decrypted text."""

import random

class Crypt(object):
	
	encryptedText = ""
	decryptedText = ""
	
	def __init__(self):
		self.text = raw_input("Gib Deinen Text ein: ")
		self.shift = int(raw_input("Um wie viele Stellen soll geshiftet werden: "))
		self.alphabet = self.randomizeAlphabet()
		self.shiftedAlphabet = self.shiftAlphabet(self.alphabet, self.shift)

		
	def main(self):
#		print self.alphabet
#		print self.shiftedAlphabet
		encryptedText = self.encrypt(self.alphabet, self.shiftedAlphabet, self.text)
		decryptedText = self.decrypt(self.alphabet, self.shiftedAlphabet, encryptedText)
		self.printText(self.text, encryptedText, decryptedText)	

		
	def randomizeAlphabet(self):
		num = 0
		bitSet = []
		alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
					'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
					'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
					'W', 'X', 'Y', 'Z', ' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!',
					'"', '$', '%', '&', '/', '(', ')', '=', '?', '{', '[', ']', '}', '.', ',', ';', 
					':', '-', '_', '<', '>', '|', '^', '*', '+', '~', '#', '@', '\\']
		randomizedAlphabet = []
		randPoolMaxInt = len(alphabet)
		for i in range(0, randPoolMaxInt):
			while num in bitSet:
				num = random.randint(0, randPoolMaxInt - 1)
			if num not in bitSet:		#if random int not in bitSet...
				bitSet.append(num)		#....set it in there
			randomizedAlphabet.append(alphabet[num])
		return randomizedAlphabet

	
	def shiftAlphabet(self, alphabet, shift):
		j = 0 
		shiftedAlphabet = []
		for i in range(shift, len(alphabet)):
			shiftedAlphabet.append(alphabet[i])
		for l in range(i - (shift - 1), len(alphabet)):
			shiftedAlphabet.append(alphabet[j])
			j += 1
		return shiftedAlphabet	

	
	def encrypt(self, alphabet, shiftedAlphabet, text):
		encryptedText = ""
		for i in range(0, len(text)):		
			for j in range(0, len(alphabet)):
				if alphabet[j] == text[i]:
					encryptedText += shiftedAlphabet[j]
					break
		return encryptedText	

	
	def decrypt(self, alphabet, shiftedAlphabet, encryptedText):
		decryptedText = ""
		for i in range(0, len(encryptedText)):
			for j in range(0, len(shiftedAlphabet)):
				if shiftedAlphabet[j] == encryptedText[i]:
					decryptedText += alphabet[j]
					break
		return decryptedText

		
	def printText(self, text, encryptedText, decryptedText):
		print
		print "Original text: %s" % (text, )
		print "Encrypted text: %s" % (encryptedText, )
		print "Decrypted text: %s" % (decryptedText, )

	
if __name__ == "__main__":
	crypt = Crypt()
	crypt.main()

Gruss

ne0h
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Einen kleinen Fehler habe ich gerade selber schon gefunden. In der randomizeAlphabet()-Methode habe ich die Variable "num"mit 0 initialisiert, was aber auch bedeutet, dass jedes Mal mit Position [0] in meiner Liste begonnen wird, ich habe das jetzt umgestellt so dass die Variable auch direkt mit einem Zufallswert initialisiert wird.


Nochmal das korrigierte Script:

Code: Alles auswählen

#!c:\python26\python.exe
# -*- coding: utf-8 -*-

#@Author: ne0h
#@Date: 06.10.2008

""" This script implements some simple encryption/decryption.
 
An pre-defined alphabet  with various characters is randomized 
with the standard randint()-method and generates a new alphabet
each time the encryption is started. After that the alphabet 
is shifted as many positions are passed in. The text passed into 
the script gets encrypted and decrypted and the last method prints 
out the original text, the encrypted text and the decrypted text."""

import random

class Crypt(object):
	
	encryptedText = ""
	decryptedText = ""
	
	def __init__(self):
		self.text = raw_input("Gib Deinen Text ein: ")
		self.shift = int(raw_input("Um wie viele Stellen soll geshiftet werden: "))
		self.alphabet = self.randomizeAlphabet()
		self.shiftedAlphabet = self.shiftAlphabet(self.alphabet, self.shift)
		

	def main(self):
#		print self.alphabet
#		print self.shiftedAlphabet
		encryptedText = self.encrypt(self.alphabet, self.shiftedAlphabet, self.text)
		decryptedText = self.decrypt(self.alphabet, self.shiftedAlphabet, encryptedText)
		self.printText(self.text, encryptedText, decryptedText)	

		
	def randomizeAlphabet(self):
		bitSet = []
		alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
					'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
					'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
					'W', 'X', 'Y', 'Z', ' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!',
					'"', '$', '%', '&', '/', '(', ')', '=', '?', '{', '[', ']', '}', '.', ',', ';', 
					':', '-', '_', '<', '>', '|', '^', '*', '+', '~', '#', '@', '\\']
		randomizedAlphabet = []
		randPoolMaxInt = len(alphabet)
		num = random.randint(0, randPoolMaxInt - 1)
		for i in range(0, randPoolMaxInt):
			while num in bitSet:
				num = random.randint(0, randPoolMaxInt - 1)
			if num not in bitSet:		#if random int not in bitSet...
				bitSet.append(num)		#....set it in there
			randomizedAlphabet.append(alphabet[num])
		return randomizedAlphabet
	

	def shiftAlphabet(self, alphabet, shift):
		j = 0 
		shiftedAlphabet = []
		for i in range(shift, len(alphabet)):
			shiftedAlphabet.append(alphabet[i])
		for l in range(i - (shift - 1), len(alphabet)):
			shiftedAlphabet.append(alphabet[j])
			j += 1
		return shiftedAlphabet	

	
	def encrypt(self, alphabet, shiftedAlphabet, text):
		encryptedText = ""
		for i in range(0, len(text)):		
			for j in range(0, len(alphabet)):
				if alphabet[j] == text[i]:
					encryptedText += shiftedAlphabet[j]
					break
		return encryptedText	

	
	def decrypt(self, alphabet, shiftedAlphabet, encryptedText):
		decryptedText = ""
		for i in range(0, len(encryptedText)):
			for j in range(0, len(shiftedAlphabet)):
				if shiftedAlphabet[j] == encryptedText[i]:
					decryptedText += alphabet[j]
					break
		return decryptedText

		
	def printText(self, text, encryptedText, decryptedText):
		print
		print "Original text: %s" % (text, )
		print "Encrypted text: %s" % (encryptedText, )
		print "Decrypted text: %s" % (decryptedText, )

	
if __name__ == "__main__":
	crypt = Crypt()
	crypt.main()
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

ne0h hat geschrieben:Was hättet Ihr in dieser ersten Rohversion anders/besser gemacht? (Es fehlen natürlich noch viele Sachen, auch entsprechende try-except Blöcke fehlen erstmal).

Code: Alles auswählen

"ne0h".decode("rot13").encode("rot13")
angesehen davon...

Ich hätte wenn dann eine Klasse die das Alphabet als Ringstruktur dargestellt... also eigentlich hätte ich es so ähnlich gemacht wie schon am Anfang des Jahres. Weiter unten gibt es noch eine Erklärung des Codes.

Was mir bei oberflächlicher Betrachtung auffällt ist, dass die Klasse Crypt irgendwie sinnlos ist. Was ist denn ein "Crypt"? Es gibt kein Objekt "Crypt" in der Realität, daher würde man auch keine Klasse dafür nutzen. Wenn deine Klassennamen Verben sind, dann bedeutet es, dass du in der Regel etwas falsch machst. Klassen "machen" nichts, dafür sind Funktionen da. Klassen "repräsentieren" etwas, Funktionen (=Verben) modifizieren es.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

maketrans ist auch nett:

Code: Alles auswählen

>>> trans = string.maketrans(string.ascii_lowercase, string.ascii_lowercase[5:] + string.letters[:5])
>>> "abcde".translate(trans)
'fghij'
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Mal abgesehen davon dass es einfacher geht, denke ich wäre es angebrachter eine Klasse zu verwenden die sich wie ein dict verhält(aber nicht unbedingt davon abgeleitet ist). Intern könnte man eine list und collections.deque verwenden. Die Liste sind die keys und deque sind die Werte die man soweit verschiebt wie man will. Man nimmt sich dann den Index des Keys in der Liste und greift damit auf die deque zu.
abgdf

Hallo,

ansonsten sind

http://sourceforge.net/projects/yawpycrypto
http://www.amk.ca/python/code/crypto

auch schöne Module. (Mein) Beispielskript dazu:

Code: Alles auswählen

#!/usr/bin/env python

import os
import sys
import base64

from yawPyCrypto.Cipher import DecryptCipher, EncryptCipher
from yawPyCrypto.Cipher import ZipDecryptCipher, ZipEncryptCipher
from yawPyCrypto.Constants import CIPHER_BLOWFISH, MODE_CBC


def doEncrypt(text, passw = None):

    e = EncryptCipher(passw, CIPHER_BLOWFISH, MODE_CBC)
    e.feed(text)
    e.finish()
    encryptedtext = e.data

    if passw != None:
        passwr = passw
    else:
        passwr = e.password

    a = (encryptedtext, passwr)
    return a


def doDecrypt(encryptedtext, passw):
    d = DecryptCipher(passw)
    d.feed(encryptedtext)
    d.finish()
    decoded = (d.data)
    return decoded


# Calling the encryption routine.
# If you just pass the text to encrypt, a password is generated:

a = doEncrypt("For your eyes only !", "Melina")


# Just trying to clean the screen:

if sys.platform == "win32":
    os.system("cls")
else:
    os.system("clear")

print
print "Hello !"
print
print "I just encrypted some text. It looks like this now:"
print

print base64.b64encode(a[0])

print
print 'Please notice, that I just encoded the text once more using "base64.b64encode()" to make it printable.'
print
print "The password for decryption is: "
print
print base64.b64encode(a[1])
print
print "Let's decrypt again (the original password must be passed without b64encoding):"
print
print doDecrypt(a[0], a[1])
print
Soll dem OP aber nicht den Spaß verderben ...

Viele Grüße
Antworten