4

私はプログラミングに不慣れで、Pythonを使用してVigenère暗号化暗号を作成しようとしています。アイデアは非常に単純であり、私の関数も同様ですが、次の行にあります。

( if((BinKey[i] == 'b')or(BinKey[i+1] == 'b')): ) 

インデックスに問題があるようですが、修正方法がわかりません。エラーメッセージは次のとおりです。

IndexError: string index out of range

おそらくpythonがを再インクリメントしていると思ったので、i+1インデックスをに等しい別の変数に置き換えようとしましたが、それでも機能しません。i+1i

だから私の質問は:

  1. 問題を解決する方法、そして私は何を間違えましたか?

  2. コードを見て、プログラミングスキルを向上させるために何を学ぶことができますか?

  3. 私は自分のプログラム(すべての暗号化暗号を含む)への単純なインターフェースを構築したいと思っています、そして私がグーグルから思いついたのはpyqtだけです、しかしそれは非常に単純なインターフェースにはあまりにも多くの仕事のようです、それでもっと簡単な方法がありますインターフェイスを構築するには?(私はEclipse IndigoとpydevをPython3.xで使用しています)

Vigenère暗号化関数(問題の原因となる行が含まれています)は次のとおりです。

def Viegner_Encyption_Cipher(Key,String):
    EncryptedMessage = ""
    i = 0
    j = 0
    BinKey = Bin_It(Key)
    BinString = Bin_It(String)
    BinKeyLengh = len(BinKey)
    BinStringLengh = len(BinString)
    while ((BinKeyLengh > i) and (BinStringLengh > j)):
        if((BinKey[i] == 'b')or(BinKey[i+1] == 'b')):
            EncryptedMessage = EncryptedMessage + BinKey[i]
        else:   
            EncryptedMessage = EncryptedMessage + Xor(BinKey[i],BinString[j])
        i = i + 1
        j = j + 1
        if (i == BinKeyLengh):
            i = i+j
    return EncryptedMessage

これはBin_It機能です:

 def Bin_It(String):
    TheBin = ""
    for Charactere in String:
         TheBin = TheBin + bin(ord(Charactere))
    return TheBin

そして最後にこれはXor関数です:

def Xor(a,b):
    xor = (int(a) and not int(b)) or (not int(a) and int(b))
    if xor:
        return chr(1)
    else:
        return chr(0)
4

4 に答える 4

4

あなたのwhile状態では、あなたはそれを確実にしていi < len(BinKey)ます。これは、それBinKey[i]が有効であることを意味しBinKey[i+1]ますが、ループの最後の反復では有効ではありませんBinKey[len(BinKey)]。これは、文字列の終わりを1つ過ぎたにアクセスするためです。Pythonの文字列は、で始まり、包括的0に終わります。len-1

これを回避するには、ループ基準を次のように更新します。

while BinKeyLength > i+1 and ...:
于 2012-11-11T11:51:23.440 に答える
4

どちらかを変更できます

while ((BinKeyLengh > i) and (BinStringLengh > j)):

while ((BinKeyLengh > i-1) and (BinStringLengh > j)):

または変更

if((BinKey[i] == 'b')or(BinKey[i+1] == 'b')):

if((BinKey[i] == 'b') or (BinKeyLengh > i-1 and BinKey[i+1] == 'b')):

BinKey[BinKeyLength]これにより、範囲外のに入るのを避けることができます。

于 2012-11-11T11:51:35.103 に答える
2

コードを見て、プログラミングスキルを向上させるために何を学ぶことができますか?

インデックスのループは慣用的なPythonではありません。可能な場合は、イテレータの要素をループすることをお勧めします。結局のところ、それは通常あなたが興味を持っているものです:for i in...多くの場合、その後にmy_list[i]

この例では、組み込み関数を使用する必要がありますzip(またはitertools.izip、コードが遅延している場合は、Python 3では必要ありません)。この関数は、2つ以上のイテレーターからの値のペアを提供し、最短のイテレーターが疲れ果てた。

for key_char, string_char in zip(BinKey, BinString):  # takes values sequentially from
                                                      # BinKey and BinString
                                                      # and binds them to the names
                                                      # key_char and string_char
    # do processing on key_char and string_char

本当にインデックスでループを実行する必要がある場合は、テストを逆に実行して、実行していることをより明確にします。while比較

while len(BinKey) > i and len(BinString) > j:  # this looks like len(BinKey) and
                                               # len(BinString) are varying and you're
                                               # comparing them to static variables i and j

while i < len(BinKey) and j < len(BinString):  # this looks like you're varying i and j
                                               # and comparing them to len(BinKey) and len(BinString)

ループの目的をよりよく伝えるのはどれですか?


最後に、条項

if (i == BinKeyLengh):
    i = i+j

何もしていないようです。その場合i == BinKeyLengthwhileループはとにかくすぐに停止します。

于 2012-11-11T12:07:41.910 に答える
1

Pythonインタープリターが言うように、あなたのエラーは、無効な配列位置にアクセスしていることだと思います。これを解決するには、言われていることとは異なり、コードを次のように変更する必要があります

while (BinKeyLength > i+2 and ...):

これは、最後のステップであるBinKeyLength = i + 2の場合、i + 1がBinKeyLength-1であり、これが配列の最後の位置であるためです。

あなたのプログラミングスキルに関して、私はあなたに2つのことをお勧めします:

  • コードになります。神秘的に聞こえますが、ここで欠落している最も重要なことは、どのインデックス番号が使用されているかを把握することです。
  • ルービックキューブで言われているように、PEP8スタイルガイドのようないくつかのスタイルガイドに従ってください。
于 2012-11-11T11:58:11.993 に答える