2013-12-16 2 views
1

Я пытаюсь кодировать файл с помощью флип-шифрования. Я написал программу для кодирования строки и работал над обычными строками. Я написал еще одну программу, чтобы прочитать файл, закодировать его в блоках, а затем записать в выходной файл. Он работает нормально около 1 МБ, но затем я получаю сообщение об ошибке. Независимо от того, какой ключ строки я использую, я получаюPython - Кодирующий файл с использованием флип-шифрования

TypeError: must be string or buffer, not None 

Я написал некоторые проверки ошибок в самой функции кодирования, и что приходит с ошибкой. Вот мой код, если кто-то может посмотреть.

Файл с функциями:

class KeyString: 
    def genNums(self): 
     self.keys = {} 
     i = 1 
     for letter in self.chars: 
      self.keys[letter] = i 
      i += 1 

    def __init__(self,chars='"LB}+h<=,.T->XcxzCdD*2Mo\RsSwj/NJ#F;kOZG!5([email protected]%Aybul_m6ag$)pf3IEtQ{0W\'K:q1HP&^v8?i`[ ~]|e)'): 
     self.chars = chars 
     self.keys = {} 
     self.genNums() 

def encode(s,k,d=False): 
    """ Encodes string 's' using string 'k' """ 
    if k == '': return s ## Makes it easier for Tribble 
    elif not len(k) >= 10: 
     print('[encd] - key too short') 
     return s 
    string = [ord(letter) for letter in s] 
    ks = KeyString() 
    try: key = [ks.keys[letter] for letter in k] 
    except: 
     print('[encd] - key not valid') 
     return s 
    length = len(string) - 1 
    loc = 0 
    for i in xrange(0,length): 
     string[i] += key[loc] 
     if string[i] > 256: string[i] -= 256 
     loc += 1 
     if loc == len(key): loc = 0 
    loc = 0 
    for i in xrange(0,length):   
     temp = 0 
     if i + key[loc] > length: temp -= length 
     else: temp = key[loc] 
     string[i],string[i+temp] = string[i+temp],string[i] 
     loc += 1 
     if loc == len(key): loc = 0 
    if d: print(s,'--->',''.join(chr(item) for item in string)) 
    try: return ''.join(chr(item) for item in string) 
    except: print('Error - ords as follows: %s' % (','.join(str(item) for item in string))) 

def decode(s,k,d=False): 
    """ Decodes string 's' using string 'k' """ 
    if k == '': return s ## Makes it easier for Tribble 
    if not len(k) >= 10: 
     print('[decd] - key too short') 
     return s 
    string = [ord(letter) for letter in s] 
    ks = KeyString() 
    try: key = [ks.keys[letter] for letter in k] 
    except: 
     print('[decd] - key not valid') 
     return s 
    length = len(string) - 1 
    loc = 0 
    for i in xrange(0,length): 
     loc += 1 
     if loc == len(key): loc = 0 
    loc -= 1 
    if loc == -1: loc = len(key) - 1 
    for i in reversed(xrange(0,length)):  
     temp = 0 
     if i + key[loc] > length: temp -= length 
     else: temp = key[loc] 
     string[i],string[i+temp] = string[i+temp],string[i] 
     loc -= 1 
     if loc == -1: loc = len(key) - 1 
    loc = 0 
    for i in xrange(0,length): 
     string[i] -= key[loc] 
     if string[i] < 1: string[i] += 256 
     loc += 1 
     if loc == len(key): loc = 0 
    if d: print(s,'--->',''.join(chr(item) for item in string)) 
    try: return ''.join(chr(item) for item in string) 
    except: print('Error - ords as follows: %s' % (','.join(str(item) for item in string))) 

class EncodeDecodeError(Exception): 
    def __init__(self,s,k,x,y): 
     self.s = s 
     self.k = k 
     self.x = x 
     self.y = y 

    def __str__(self): 
     return repr('Encode/decode test failed on s=%s k=%s x=%s y=%s' % (self.s,self.k,self.x,self.y)) 

## The following just tests the encode/decode functions 
## and raises an error if it fails 
random.seed() 

test = True 
print('Running encode/decode test...') 
for i in xrange(1,1000): ## len(str(i)) <= 5 is the important part 
    s = str(random.randint(0,i)) 
    k = str(random.randint(1000000000,10000000000)) 
    x = encode(s,k,False) 
    y = decode(x,k,False) 
    if not y == s: raise EncodeDecodeError(s,k,x,y) 
print('Done encode/decode test!') 

Ошибка возникает где-то в функции кодирования.

Вот программа для шифрования файлов:

import argparse 
import sys 
from os import path 
from functools import partial 

parser = argparse.ArgumentParser() 
parser.add_argument('src',help='source file') 
parser.add_argument('out',help='output file') 
parser.add_argument('key',help='key to use') 
parser.add_argument('-d','--decode',action='store_true',help='decode file') 

args = parser.parse_args() 

if not path.isfile(args.src): 
    print 'Source file "%s" not found' % args.src 
    sys.exit(1) 

with open(args.src,'rb') as src: 
    out = open(args.out,'wb') 
    i = 0 
    for chunk in iter(partial(src.read,1024),''): 
     if not args.decode: x = encode(str(chunk),args.key) 
     else: x = decode(str(chunk),args.key) 
     out.write(x) 
     print '%s kb' % (i) 
     i += 1 
    out.close() 

я импортировал файл с функциями закодировать, я просто оставил, что импорт в коде.

ответ

1

Входной файл содержит байты в диапазоне 0-255, а в python2 функция chr может возвращать только символы в этом диапазоне:

>>> chr(256) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: chr() arg not in range(256) 

Проблема в коде на этой линии:

if string[i] > 256: string[i] -= 256 

, который, в зависимости от входа, будет иногда позволять string содержать 256 (т.е. есть «выключено-по-одному» ошибка). Таким образом, очевидно, что способ исправить это просто:

if string[i] > 255: string[i] -= 255 
Смежные вопросы