简体   繁体   English

我如何在python中的文件上使用rot 13

[英]how do i use rot 13 on a file in python

im trying to rewrite every character in a file with rot 13 and im stuck, im not sure how to go through the file and look at every character and not worry about the spaces between paragraphs 我试图用腐烂13重写文件中的每个字符,并且卡住了,我不确定如何浏览文件并查看每个字符,而不用担心段落之间的空格

# [import statements]
import q2fun
# [constants]

# [rest of program code]
f = open("rot-13.txt", "w", encoding="utf-8")
result = q2fun.rot13(f)

def rot13(f):

    f.seek(0)
#   y = 0
    result = ""
    for char in f:
        x = ord(char)
        if 97 <= x < 110 or 65 <= x < 78:
#           string[y]=char.replace(char, chr(x+13))
            char = char.replace(char, chr(x + 13))
            result = result + char
            print(char)
            continue
#           y+=1
        elif x >= 110 or 78 <= x < 91:
#           string[y]=char.replace(char, chr(x-13))
            char = char.replace(char, chr(x - 13))
            print(char)
            result = result + char
            continue
#           y+=1
        result = result + char
    return result
import codecs


with open("plaintext.txt") as f_in, open("rot-13.txt", "w") as f_out:
    f_out.write(codecs.encode(f_in.read(),"rot_13"))

with open("rot-13.txt") as encoded:
    print (codecs.decode(encoded.read(),"rot_13"))

See the documentation on the codecs module, or the built-in help in the interactive interpreter, for an explanation of these functions. 有关这些功能的说明,请参见codecs模块上的文档或交互式解释codecs的内置help See the documentation on the Standard Encodings (and following sections), or import the encodings module and use the built-in help , to see a list of encodings you can use with these functions. 请参阅“ 标准编码” (及以下各节)上的文档,或导入“ encodings模块并使用内置的help ,以查看可用于这些功能的编码列表。

If you just want to do this as easily as possible, use the rot_13 codec, as described in Joran Beasley's answer. 如果您只想尽可能轻松地执行此操作,请使用rot_13编解码器,如Joran Beasley的回答所述。

If you want to know how to do it manually, or what was wrong with your existing code, I can explain. 如果您想知道如何手动进行操作,或者您现有的代码出了什么问题,我可以解释一下。 You're actually very close. 你真的很亲密

If f is a file, for char in f: iterates over the lines of the file, not the characters . 如果f是文件,则for char in f:遍历文件的各 ,而不遍历所有字符 If you want to iterate over the characters one by one, either loop around f.read(1) , or read the whole thing into a string with s = f.read() and then iterate over s . 如果要一遍遍地遍历这些字符,请在f.read(1)周围循环,或者将整个内容读入s = f.read()的字符串中,然后遍历s

If you fix that, your program now works as written. 如果您解决了该问题,则程序现在可以按编写的方式工作。 However, it's more complicated than necessary. 但是,它比必需的更为复杂。

First, char = char.replace(char, chr(x + 13)) is unnecessary. 首先, char = char.replace(char, chr(x + 13)) str.replace searches the string, substitutes the replacement character for all instances of the search character, and returns the resulting string. str.replace搜索字符串,将替换字符替换为搜索字符的所有实例,然后返回结果字符串。 But you don't need any of that—you're searching all one character, replacing the one instance of the search character with the resulting character, and returning the resulting character as a one-character string—in other words, the same string you already had. 但是您不需要任何这些-您要搜索所有一个字符,将搜索字符的一个实例替换为结果字符,然后将结果字符作为一个单字符字符串返回-换句话说,相同的字符串你已经有。 All you want to do here is char = chr(x + 13) . 您只想在这里做char = chr(x + 13)

Also, you can remove the three separate result = result + char and continue ; 另外,您可以删除三个单独的result = result + charcontinue ; all three conditions lead to the same thing. 所有这三个条件导致同一件事。

Also, instead of comparing x to ordinal values (which are hard to read, and easy to get wrong), you can just compare char to character values. 另外,您可以将char与字符值进行比较,而不是将x与顺序值(难以阅读且容易出错)进行比较。 So: 所以:

def rot13(f):
    s = f.read()
    result = ""
    for char in s:
        x = ord(char)
        if 'a' <= char <= 'm' or 'A' <= char <= 'M':
            char = chr(x + 13)
        elif 'n' <= char <= 'z' or 'N' <= char <= 'Z':
            char = chr(x - 13)
        result = result + char
    return result

You can simplify your comparisons further by using str.lower : 您可以使用str.lower进一步简化比较:

        if 'a' <= char.lower() <= 'm':

(This replaces the if 'a'… line in the above code, and you do the same thing for the elif 'n'… line.) (这取代了if 'a'…线在上面的代码,你做了同样的事情elif 'n'…行。)

You can simplify things even further by using the collections in the string class: 您可以使用string类中的集合来进一步简化事情:

        if char in string.ascii_letters:
            if char.lower() <= 'm':
                char = chr(x + 13)
            else:
                char = chr(x - 13)

(This replaces the whole if / elif block.) (这将替换整个if / elif块。)

Or, if you know that the % (mod/remainder) operator does, you can simplify it even further: rot13(ch) is just (ch+13) % 26 (where ch is a letter number from 0 to 25 , which you can get with ord(char) % 32 ). 或者,如果您知道% (mod / remainder)运算符的作用,则可以进一步简化它: rot13(ch)只是(ch+13) % 26 (其中ch是从025的字母数字,您可以可以使用ord(char) % 32 )获得。 The usual C implementations take advantage of this, and you can write them more clearly with the divmod function in Python. 常规的C实现利用了这一点,您可以使用python中的divmod函数将其更清楚地编写。 But I'll leave that as an exercise for the reader. 但我会将其留给读者练习。

An old-school implementation with python3 python3的老式实现


def ROT_13(realText):
    outText = ""
    cryptText = []
    step = 13
    uppercase = ['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']
    lowercase = ['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']
    puncuation = [",","'",":","!","~","`","@","#","$","%","^","&","*","(",")","-","_","+","=","<",">","/","?",";","\\","|","{","}","[","]"]

    for eachLetter in realText:
        if eachLetter in uppercase:
            index = uppercase.index(eachLetter)
            crypting = (index + step) % 26
            #print("{}  index={} Crypt={}".format(eachLetter,index,crypting))
            cryptText.append(crypting)
            newLetter = uppercase[crypting]
            outText += (newLetter)
        elif eachLetter in lowercase:
            index = lowercase.index(eachLetter)
            crypting = (index + step) % 26
            #print("{}  index={} Crypt={}".format(eachLetter,index,crypting))
            cryptText.append(crypting)
            newLetter = lowercase[crypting]
            outText += (newLetter)
        elif eachLetter in puncuation:
          outText += eachLetter 
        else:
          outText += " "
    return outText

You may call it like this 你可以这样称呼它

code = ROT_13("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
print(code)

to get the result 得到结果

NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

it even handles spaces, special characters as , # and CAPS 它甚至可以处理空格,特殊字符,如#和CAPS

code2 = ROT_13("it even handles spaces, special characters as , # and CAPS")

to get 要得到

"vg rira unaqyrf fcnprf, fcrpvny punenpgref nf , # naq PNCF"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM