替代换行符?蟒蛇

时间:2009-05-12 15:35:11

标签: python

我正在寻找一种只用一个字符代表'\ n'的方法。我正在编写一个使用字典来“加密”文本的程序。因为每个字符都在字典中表示,当我的程序到达字符串中的'\ n'时,我遇到了问题,但是将其读作'\''n'。是否有替代方式来表示换行符,即只有一个字符? 这是我的下面的代码,对不起,如果某些缩进搞砸了。我不完全理解如何在此窗口中输入代码。 :)

##################################
#This program will take an input and encrypt it or decrypt it
#A cipher is used to transform the text, which can either be
#input or from a text file.
#The cipher can be any letter a-z, as well as most commonly used special characters
#numbers and spaces are not allowed.
#For the text, a-z, most special characters, space, and new line may be used.
#no numbers can be encrypted.
##################################

#These three dictionaries are used during the encryption process.
keyDict={'a': 17,'b': 3,'c':16,'d':26,'e':6,'f':19,'g':10,'h':12,
         'i':22,'j':8,'k': 11,'l':2,'m':18,'n':9,'o':23,'p':7,
         'q':5,'r': 20,'s': 1,'t': 24,'u':13,'v':25,'w':21,'x':15,
         'y':4,'z': 14, ' ':42, '.':0,'!': 27, '@': 34, '#': 35, '%': 37,
         '$': 36, "'": 33,'&': 39, '*': 40, ',': 29, '.': 30, '~': 41, ';': 31,
         ':': 32, '?': 28, '^': 38}

refDict2={' ': 43,  'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4, 'g': 7, 'f': 6, 'i': 9,
         'h': 8, 'k': 11, 'j': 10, 'm': 13, 'l': 12, 'o': 15, 'n': 14, 'q': 17,'\n': 42,
         'p': 16, 's': 19, 'r': 18, 'u': 21, 't': 20, 'w': 23, 'v': 22, 'y': 25,
         'x': 24, 'z': 26, ' ':0, '!': 27, '@': 34, '#': 35, '%': 37, '$': 36, "'": 33,
          '&': 39, '*': 40, ',': 29, '.': 30, '~': 41, ';': 31, ':': 32, '?': 28, '^': 38}

refDict={0: ' ', 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i',
         10: 'j', 11: 'k', 12: 'l', 13: 'm', 14: 'n', 15: 'o', 16: 'p', 17: 'q', 42:'\n',
         18: 'r', 19: 's', 20: 't', 21: 'u', 22: 'v', 23: 'w', 24: 'x', 25: 'y', 26: 'z', 43:' ',
         32: ':', 33: "'", 34: '@', 35: '#', 36: '$', 37: '%', 38: '^', 39: '&', 40: '*',
         41: '~', 27: '!', 28: '?', 29: ',', 30: '.', 31: ';'}


#switch1 reverses a list. It is its own inverse, so we don't need an unswitch function. 
def switch1(l):
    return l[::-1]



#switch2 takes a list as input and moves every fourth entry to the front
#so switch2([a,b,c,d,e,f,g]) returns ([a,e,b,c,d,f,g])
#unswitch2 undoes this, so unswitch2([a,e,c,d,f,g]) returns [a,b,c,d,e,f,g]

def switch2(l):
    List4 = []
    ListNot4 = []
    for i in range(0,len(l)):
        if i%4 == 0:
            List4.append(l[i])
        else:
            ListNot4.append(l[i])
    return List4+ListNot4

def unswitch2(l):
    num4 = len(l)/4 + 1
    fixedList = l[num4:]
    for i in range (0,num4):
        fixedList.insert(4*i,l[i])
    return fixedList



#switch3 takes a list as input and returns a list with the first half moved to the end.
#so switch3([a,b,c,d,e,f]) returns [d,e,f,a,b,c]
#for lists of odd length, switch3 puts the separation closer to the beginning of the list, so the
#middle entry becomes the first entry.
#For example, switch3([a,b,c,d,e,f,g]) returns [d,e,f,g,a,b,c]

def switch3(l):
    return l[len(l)/2:] + l[:len(l)/2]

def unswitch3(l):
    if len(l)%2==0:
        return switch3(l)
    else:
        return l[len(l)/2+1:] + l[:len(l)/2+1]




##################################
#This is the Crypt function.
##################################
def Crypt(text, cipher):
    counter=0
    text=text.lower()
    cipher=cipher.lower()
    keyValue=[]
    textValue=[]
    newValue=[]
    newString=''
    for letter in cipher:
        keyValue.append(keyDict[letter])

    for letter in text:
        textValue.append(refDict2[letter])

    for num in textValue:
        newValue.append(num+keyValue[counter%len(keyValue)])
        counter+=1

    newValue = switch1(newValue)
    newValue = switch2(newValue)
    newValue = switch3(newValue)

    for num in newValue:
        newString+=refDict[num%43]

    return newString

##################################
#This is the Decrypt function
##################################
def Decrypt(encryptedText, cipher):
    counter=0
    cipher=cipher.lower()
    keyValue=[]
    textValue=[]
    finalValue=[]
    finalString=''

    for letter in encryptedText:
        textValue.append(refDict2[letter])

    textValue = unswitch3(textValue)
    textValue = unswitch2(textValue)
    textValue = switch1(textValue)

    for letter in cipher:
        keyValue.append(keyDict[letter])

    for num in textValue:
        finalValue.append((num-keyValue[counter%len(keyValue)])%43)
        counter+=1


    for num in finalValue:
        finalString+=refDict[num]

    return finalString


##################################
#This is the user interface.
##################################

choice=raw_input('Would you like to: 1)Encrypt or 2)Decrypt?  Pick 1 or 2: ')

if choice=='1':
    textType=raw_input("Would you like to: 1)encrypt a text file or 2) input the text to be encrypted? Pick 1 or 2: ")

    if textType=='1':
        cryptName=raw_input( 'Please enter the name of the text file you would like to encrypt(eg. text.txt): ')
        newName=raw_input('Please name the file in which the encrypted text will be stored(eg. secret.txt):' )
        cipher=raw_input("Now enter your personal encryption key(eg. secret code):" )

        cryptFile=open(cryptName, 'r')
        newFile=open(newName, 'w')
        print >> newFile, Crypt(cryptFile.read(),cipher)
        cryptFile.close()
        newFile.close()
        print "Ok, all done!"
    elif textType=='2':
        inputText=raw_input('Ok, please input the text you would like to encrypt(eg. computers rock!): ')
        cipher=raw_input("Now enter your personal encryption key (eg. ultra secret code): ")
        if inputText=='': print 'Oops, no text was entered! Try again!'
        else:
            print Crypt(inputText, cipher)
    else:
        print 'Try again!'

elif choice=='2':
    textType=raw_input("Would you like to:1)decrypt a text file or 2) input the text to be decrypted? Pick 1 or 2: ")
    if textType=='1':
        decryptName=raw_input( 'Please enter the name of the text file you would like to decrypt(eg. text.txt): ')
        newName2=raw_input('Please name the file in which the decrypted text will be stored(eg. secret.txt):' )
        cipher=raw_input("Now enter the encryption key that was used to encrypt the file(eg. secret code):" )
        #Text decrypt
        decryptFile=open(decryptName, 'r')
        newFile2=open(newName2, 'w')
        print>> newFile2, Decrypt(decryptFile.read(),cipher)
        #other stuff
        #textTodecrypt=decryptFile.read()
        #newFile2.writelines(Decrypt(textTodecrypt, cipher))


        decryptFile.close()
        newFile2.close()
        print "Ok, all done!"

    elif textType=='2':
        inputText=raw_input('Ok, please input the text you would like to decrypt(eg. dig&ak:do): ')
        cipher=raw_input("Now enter the encryption key that was used to encrypt the text (eg. ultra secret code): ")
        if inputText=='': print 'Oops, no text was entered! Try again!'
        else:
            print Decrypt(inputText, cipher)

print "Have a nice day!"


#there is an issue with the newline character 

7 个答案:

答案 0 :(得分:9)

'\ n'是一个字符。它是一个新的换行字符,只是新行的表示。

请以可读的方式重新解释您的问题。

[编辑] 我想我知道你的问题是什么。我运行你的程序,它工作得很好。您可能正在尝试从命令行将'\ n'传递给您的程序。那样不行!

你知道,如果你给了raw_input()这个字符串:line1\nline2它会逃脱\n并将它\\n改为:'line1\\nline2'

所以快速解决问题的方法是找到并用'\ n'替换'\\ n':

text.replace('\\n', '\n')

我不喜欢这个。但它会对你有用。

更好的方法是读取多行,如下所示:

input = raw_input('Please type in something: ')
lines = [input]
while input:
    input = raw_input()
    lines.append(input)

text = '\n'.join(lines)

print text

答案 1 :(得分:4)

我猜你真正的问题不在于读取\ n作为'\''n' - 在内部,Python应该自动将\ n翻译成单个字符。

我的猜测是真正的问题是你的新行可能实际上是两个字符 - 回车符('\ r')和换行符('\ n')。除了\ n之外,请尝试处理\ r \ n,我想知道这是否会让您的问题消失。

答案 2 :(得分:4)

我认为问题是如果文本中有\ n要解密,它会中断:

KeyError: \

module body   in untitled at line 166
function Crypt    in untitled at line 94

基本上,raw_input()会返回一个包含两个字符\n的字符串 - 而且您没有映射\错误。

最简单的解决方案就是简单地用\n转义序列替换文字字符\n

def Crypt(text, cipher):
    text.replace(r"\n", "\n")
    ... 

原始字符串r"\n"创建一个字符串,其中包含文字字符\,后跟n(与执行"\\n"相同)。

在常规字符串"\n"中,它被视为换行符的转义序列。因此,上面的代码块用换行符替换文本中的\n

您可能必须在keyDict映射中为“\ n”定义映射。

另一种解决方案是使用text.split(r"\n")拆分文本并分别处理每一行。或者正如其他人所建议的那样,使用ord()每个字符并处理数字,而不是自己进行数字映射。

  

ord(c)   给定一个长度为1的字符串,当参数是unicode对象时返回表示字符的Unicode代码点的整数,或者当参数是8位字符串时返回字节的值。例如,ord('a')返回整数97,ord(u'\u2020')返回8224.对于8位字符串,这是chr()的倒数,对于unicode对象,则是unichr()的倒数。

正如文档所解释的那样,chr()是相反的,并且会将数字转换回ASCII或Unicode字符:

  

chr(i)   返回一个字符串,其ASCII码为整数i。例如,chr(97)返回字符串'a'。这是ord()的倒数。参数必须在[0..255]范围内,包括在内;如果i超出该范围,则会引发ValueError。

基本上你会做..

def Crypt(text, cipher):
    keyvalue = [ord(x) for x in cipher)
    textvalue = [ord(x) for x in text]

..而不是两个for循环(list-comprehension基本上与制作列表相同,循环遍历文本或密码中的每个字符,并且每次都附加到列表中)

答案 3 :(得分:3)

换行符是单个字符。

>>> a = '\n'
>>> print len(a)
1
>>> a = '\n\n\n'
>>> a[1]
'\n'
>>> len(a)
3
>>> len(a[0])
1

所以你误解了你的问题。

答案 4 :(得分:2)

我是Python的新手,但是可以通过使用 ord chr 函数将字符更改为ASCII值来简化您的工作。反之亦然。这是built-in function documentation in Python的链接。

答案 5 :(得分:1)

您应该利用数字的数值来执行加密,并避免那些无法用于非ascii文本的大数据结构。

答案 6 :(得分:0)

使用str.decode方法替换常用转义符的简单快捷方法是使用>>> s = r'This string has\tsome\nescapes' >>> s 'This string has\\tsome\\nescapes' >>> s.decode('string-escape') 'This string has\tsome\nescapes' >>> print s This string has\tsome\nescapes >>> print s.decode('string-escape') This string has some escapes 方法:

{{1}}