-1

現在、rot 13 を使用してテキストを暗号化する割り当てを行っていますが、テキストの一部が登録されません。

# cgi is to escape html
# import cgi

def rot13(s):
    #string encrypted
    scrypt=''
    alph='abcdefghijklmonpqrstuvwxyz'
    for c in s:
        # check if char is in alphabet
        if c.lower() in alph:
            #find c in alph and return its place
            i = alph.find(c.lower())

            #encrypt char = c incremented by 13
            ccrypt = alph[ i+13 : i+14 ]

            #add encrypted char to string
            if c==c.lower():
                scrypt+=ccrypt
            if c==c.upper():
                scrypt+=ccrypt.upper()

        #dont encrypt special chars or spaces
        else:
            scrypt+=c

    return scrypt
    # return cgi.escape(scrypt, quote = True)


given_string = 'Rot13 Test'
print rot13(given_string) 

出力:

13 r
[Finished in 0.0s]
4

5 に答える 5

2

うーん、たくさんのことが機能していないようです。主な問題は次のccrypt = alph[ i+13 : i+14 ]とおりです。% len(alph)たとえば、iがに等しい場合18は、リストの境界から外れてしまいます。実際、出力では、13だけ移動しても境界を超えない、テスト文字列内の唯一の文字であるため、にのみeエンコードされます。r

この回答の残りの部分は、コードを少しクリーンアップするためのヒントにすぎません。

  • 代わりに、スクリプトの最初でをalph='abc..宣言して、import stringstring.lowercase
  • 文字列のスライスを使用する代わりに、1文字だけを使用する方が適切でstring[i]あり、作業を完了します
  • の代わりにc == c.upper()、組み込み関数を使用できますif c.isupper() ...
于 2012-12-12T23:43:32.507 に答える
2

あなたが抱えている問題はあなたのスライスにあります。あなたのキャラクターがアルファベットの後半にある場合、それはi+13終わりから外れるので、それは空になります。あなたがそれを修正することができるいくつかの方法があります。

最も簡単なのは、アルファベットの文字列を単純に2倍にすることです(文字通り:) alph = alph * 2。これは、最大26ではなく、最大52の値にアクセスできることを意味します。ただし、これはかなり大雑把な解決策であり、インデックスを修正する方がよいでしょう。

13を加算するのではなく、インデックスから13を減算することをお勧めします。Rot13は対称であるため、どちらも同じ効果があり、Pythonでは負のインデックスが有効であるため機能します(末尾から逆方向にカウントされた位置を参照します)。 )。

どちらの場合も、実際にはスライスを行う必要はまったくありません。単純に単一の値を取得できます(Cとは異なりchar、Pythonには型がないため、単一の文字も文字列です)。この変更のみを行うと、文字列の末尾から1つの値にアクセスしようとすると例外が発生するため、現在のコードが失敗する理由が明らかになる可能性があります。

編集:実際、どのソリューションが本当に最適かを考えた後、インデックス数学ベースのソリューションを完全に回避することを提案する傾向があります。より良いアプローチは、Pythonの素晴らしい辞書を使用して、元の文字から暗号化された文字へのマッピングを行うことです。次のようなRot13辞書を作成して使用できます。

alph="abcdefghijklmnopqrstuvwxyz"
rot13_table = dict(zip(alph, alph[13:]+alph[:13])) # lowercase character mappings
rot13_table.update((c.upper(),rot13_table[c].upper()) for c in alph) # upppercase

def rot13(s):
    return "".join(rot13_table.get(c, c) for c in s) # non-letters are ignored
于 2012-12-12T23:44:00.087 に答える
1

この行

ccrypt = alph[ i+13 : i+14 ]

思ったとおりに動作しません-からi+13への文字列スライスを返しますi+14が、これらのインデックスが文字列の長さよりも大きい場合、スライスは空になります。

"abc"[5:6] #returns ''

これは、ソリューションがnそれ以降のすべてを空の文字列に変換し、観測された出力を生成することを意味します。

これを実装する正しい方法は、(1。)モジュロ演算を使用してインデックスを有効な数値に制約すること、および(2.)文字列スライスの代わりに単純な文字アクセスを使用することIndexErrorです。無効なインデックス。つまり、エラーは明らかでした。

ccrypt = alph[(i+13) % 26]
于 2012-12-12T23:43:49.357 に答える
1

いくつかの問題を引き起こした可能性のある最初のこと-文字列リストにはとno切り替えられているので、それを調整する必要があります:)アルゴリズムに関しては、実行するときに:

ccrypt = alph[ i+13 : i+14 ]

25最初の反復(の)から戻ったときに何が起こるかを考えてくださいz。現在、インデックス位置を探していますalph[38:39](補足:実際には言うことができますalph[38])。これは、26文字の文字列の境界をはるかに超えており、次のようになります''

In [1]: s = 'abcde'

In [2]: s[2]
Out[2]: 'c'

In [3]: s[2:3]
Out[3]: 'c'

In [4]: s[49:50]
Out[4]: ''

それを修正する方法に関しては、いくつかの興味深い方法があります。コードは、いくつかの変更を加えるだけで問題なく機能します。あなたができることの1つは、すでに「回転」している13の位置にあるキャラクターのマッピングを作成することです。

alph = 'abcdefghijklmnopqrstuvwxyz'
coded = 'nopqrstuvwxyzabcdefghijklm'

ここで行ったのは、元のリストを13の半分に分割し、それらを交換することだけです。たとえば、のような文字aを取得してその位置(0)を取得すると、コード化されたリストの同じ位置がrot13値になることがわかります。これは課題のためのものなので、その方法を詳しく説明しませんが、それが正しい方向に進むかどうかを確認します(@Makotoの提案は結果を確認するのに最適な方法です)。

于 2012-12-12T23:44:10.163 に答える