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

时间:2013-11-25 19:38:57

标签: python

我试图用rot 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

3 个答案:

答案 0 :(得分:2)

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"))

有关这些功能的说明,请参阅codecs模块上的文档或交互式解释器中的内置help。请参阅Standard Encodings(以及后续部分)上的文档,或导入encodings模块并使用内置help,查看可与这些功能一起使用的编码列表。

答案 1 :(得分:2)

如果您只想尽可能轻松地执行此操作,请使用rot_13编解码器,如Joran Beasley的回答所述。

如果你想知道如何手动操作,或者现有代码有什么问题,我可以解释一下。你实际上非常接近。

如果f是文件,for char in f:将遍历文件的,而不是字符。如果您想逐个遍历字符,请循环f.read(1),或者将整个内容读入包含s = f.read()的字符串,然后迭代s

如果您解决了这个问题,您的程序现在可以按照书面形式运行但是,它比必要的更复杂。

首先,char = char.replace(char, chr(x + 13))是不必要的。 str.replace搜索字符串,将替换字符替换为搜索字符的所有实例,并返回结果字符串。但是你不需要任何一个 - 你正在搜索所有一个字符,用结果字符替换搜索字符的一个实例,并将结果字符作为单字符字符串返回 - 换句话说,你已经拥有的相同字符串。你想在这里做的只是char = chr(x + 13)

此外,您可以删除三个单独的result = result + charcontinue;这三个条件导致了同样的事情。

此外,您可以将x与字符值进行比较,而不是将char与有序值(难以阅读,容易出错)进行比较。所以:

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

您可以使用str.lower

进一步简化比较
        if 'a' <= char.lower() <= 'm':

(这会替换上面代码中的if 'a'…行,并为elif 'n'…行做同样的事情。)

您可以使用string类中的集合来进一步简化:

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

(这取代了整个if / elif块。)

或者,如果您知道%(mod / remainder)运算符,则可以进一步简化:rot13(ch)只是(ch+13) % 26(其中ch是从025的字母编号,您可以使用ord(char) % 32获得该编号。通常的C实现利用了这一点,您可以使用Python中的divmod函数更清楚地编写它们。但我会把它留作读者的练习。

答案 2 :(得分:0)

使用python3的老式实现

public static string Post(string url, string jsonContent)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    //request.Headers.Add(HttpRequestHeader.Authorization, API_AUTHORIZATION_HEADER);
    request.Method = "POST";

    System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    Byte[] byteArray = encoding.GetBytes(jsonContent);
}

您可以这样称呼


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

获得结果

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

它甚至可以处理空格,特殊字符,如#和CAPS

NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

获得

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