[アルゴリズム]起動パスワード



※この写真と投稿内容の問題は、ProgrammersのWebサイトから抜粋しています.

💬 入る前に...


💢 シーザーのパスワードは何ですか?
シーザーパスワード.
暗号学における簡単な「置換パスワード」です.
△実はローマの皇帝シーザーが使っていたそうです.
このパスワードは、暗号化する内容をアルファベットで一定の距離で別のアルファベットにプッシュする方法です.
たとえば、シーザーのパスワードを3文字ずつ使用します.
暗号化「COME TO ROME」は「FRPH WR URPH」になります.
解読「RUSQHUVKBVHVHQIIQDQJEH」
「BECAREFULFORASASINATOR」(刺客注意)となる
ここで提示される文字数は、パスワードを送信した人とともに決定され、より難しいパスワードが生成されます.=パスワードのループ
しかし、暗号化する内容には必ず繰り返し使用するか、必ず使用しなければならないフレーズもあります.
スペルの頻度やよく使われる単語や形式を利用して、
欠点は解きやすいことです.
※出典Wikipediaシーザーのパスワード

に質問

어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 
예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. 
"z"는 1만큼 밀면 "a"가 됩니다. 
문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.

제한 조건 :
공백은 아무리 밀어도 공백입니다.
s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.
s의 길이는 8000이하입니다.
n은 1 이상, 25이하인 자연수입니다.

<입출력 >
s	| n	| result
"AB"	| 1	| "BC"
"z"	| 1	| "a"
"a B z"	| 4	| "e F d"

ほどく


My Code

def solution(s, n):
    ls = []
    for a in s :
        if a.isspace() : 
            ls.append(a)
        else :
            ascii = ord(a)
            if ascii >= 65 and ascii < 91:
                if (ascii+n) >= 91 :
                    ascii = (ascii+n) - 26
                    new_w = chr(ascii)
                else :
                    new_w = chr(ascii+n)
            elif ascii >= 97 and ascii < 123 :
                if (ascii+n) >= 123 :
                    ascii = (ascii+n) - 26
                    new_w = chr(ascii)
                else :
                    new_w = chr(ascii+n)
            ls.append(new_w)
    return ''.join(ls)
複雑な解決の感覚がないわけではない.
ASCIIコード(ASCIIコード)を用いて解読した.
Pythonのchr()関数とord()関数は、このASKIDコードを使用する関数です.
まず,chr()関数は整数(int)値を引数として受け入れる.対応する整数の文字を返す関数です.ord()関数は、受信文字(str)値を引数として返し、その文字のコード値を返します.
これらの関数の特徴を利用して
まず,入力した文字列をfor文としてif~else文に逐字適用する.
(バカみたいに、分離空白のlist()関数を利用していない…)
ここで重要なのは
スペースがある可能性があるため、スペースは.isspace()にフィルタされます.
結果値を直接導出するために、繰り返しを必要とせずにls上でappendを直接行った.
空白ではありません.
この文字のasciiコード値は、asciiという変数ord()関数を使用して格納されます.
その後、私は二重条件をしました.
まず、大文字(if ascii >= 65 and ascii < 91:)であれば.
ストレッチの結果がZを超える場合、そのアトリビュートは時間間隔です.
Aから再開するから.if (ascii+n) >= 91 :でフィルタリングし、(ascii + n)で26を減算して再宣言し、chr()で返された値をnew wという変数に代入します.
Zを超えない残りの部分はchr(ascii + n)に直接代入される.
小文字(elif ascii >= 97 and ascii < 123 :)についても同様の方法で解決できる.
次にnew値をfor文の最後のlsに追加します.''.join(ls)Returnは、暗号化の開始パスワード値を返します.

※ソースㅢㅣGoogleなら見つけやすい李在旭が作成したASCIIコードシート

説明する


(1)
def caesar(s, n):
    s = list(s)
    for i in range(len(s)):
        if s[i].isupper():
            s[i]=chr((ord(s[i])-ord('A')+ n)%26+ord('A'))
        elif s[i].islower():
            s[i]=chr((ord(s[i])-ord('a')+ n)%26+ord('a'))

    return "".join(s)
このプールは私と同じASCIIコードord()関数、chr()関数を使用します.
私の答えより簡潔な理由は
まずlist()関数を使用
クエリ範囲にはrange(len(list(s))が使用されています.
簡単に.isupper()で大文字と小文字を区別し、islower()で大文字と小文字を区別します.
様々な場合に適したAとAのord()値を利用した.
どちらの場合も適用されない場合は、
空白の場合、変更はありません.
for文で修正が完了したリストsを返し、スペース"".join(s)を残さない.
(2)
import string
def caesar(s, n):
    result = ""
    base = ""
    for c in s:
        if c in string.ascii_lowercase:
            base = string.ascii_lowercase
        elif c in string.ascii_uppercase:
            base = string.ascii_uppercase
        else:
            result += c
            continue
        a = base.index(c) + n
        result += base[a % len(base)]
    return result
まずstringモジュールを使うことに慣れていない答えです.
このstringモジュールは不思議です
この問題のために存在するように.string.ascii_lowercase/string.ascii_uppercase.
これに対して,inという方法を用いて,各アルファベットに対応する位置を決定した.
for文に入る前にresultとbaseという空の文字列変数を作成します.
for文では、baseが上記の条件文に対応する場合、対応するセットが適用されます.
aという名前の変数にbase.index(암호내용 알파벳) + nを入力します.
resultでは、base[a % len(base)](a変数の集合長が残りのzを超えると防止)の値を順番に入力します.
else条件の場合、result += c ; continueに加算できるコマンドがあります.
これは空白に対する命令です.
これにより、累積完了したresult変数が返されます.