変換がアルファベットのシフトと同じくらい単純な場合は、次の方法で簡単に実行できます。
if original_character.isupper(): # Determine whether it is upper/lower case
base_a = 'A' # use 'A' as a base for uppercase
else: #
base_a = 'a' # use 'a' as a base for lowercase
orig_char_ascii = ord(original_character) # Get the original ascii value
orig_char_alpha_index = orig_char_ascii - ord(base_a) # Get the `0-25` alphabetic
# index of the character
shift_number = 3 # Set the amount to shift by
new_char_alpha_index = orig_char_alpha_index + shift_number # Add the shift value
new_char_alpha_index = new_char_alpha_index % 26 # Take the modulus to impose
# periodic boundary conditions
# i.e. if you had 'z' + 3
# 'z' + 3 -> 25 + 3 -> 28
# 28 % 26 = 2, 2 -> 'c'
new_char_ascii_index = ord(base_a) + new_char_alpha_index # scale back to the ascii
# value
new_char = chr(new_char_ascii_index)
ord
基本的な考え方は、各文字が(つまり)によって取得できる ASCII 番号に対応するということord('a') = 97
です。メソッドはこれchr
を逆にします: chr(97) = 'a'
.
メソッドは簡単です: ascii 値を取得し、0 ~ 25 のアルファベット範囲にスケーリングし、シフトを追加し、アルファベット範囲を超えた値をラップし、ascii にスケール バックし、 を介して文字を取得しchr
ます。
このメソッドを大幅に圧縮できます。私は教育の名の下に冗長でした。
def shift_char(ch,shift):
if not ch.isalpha():
return ch # return non-alphabetic characters as is
is_upper = 'A' <= original_character <= 'Z'
if is_upper:
base_a = 'A'
else:
base_a = 'a'
return chr(ord(base_a) + (ord(ch)-ord(base_a)+shift)%26)
文字列全体に同じランダム シフトを使用する場合は、これをいくつかの方法に分割できます。
def shift_char(ch,shift):
if not ch.isalpha():
return ch # return non-alphabetic characters as is
if ch.isupper():
base_a = 'A'
else:
base_a = 'a'
return chr(ord(base_a) + (ord(ch)-ord(base_a)+shift)%26)
def shift_string(s,shift):
return ''.join(shift_char(i,r) for i in s)
後でデコードできるようにしたい場合は、反転メソッドとシフト値を保存する必要があります。
def shift_char(ch,shift):
if not ch.isalpha():
return ch # return non-alphabetic characters as is
if ch.isupper():
base_a = 'A'
else:
base_a = 'a'
return chr(ord(base_a) + (ord(ch)-ord(base_a)+shift)%26)
def encode_string(s,shift):
return ''.join(shift_char(i,r) for i in s), shift # NOTE EXTRA return value
def decode_string(s,shift):
return ''.join(shift_char(i,-shift) for i in s)
# usage
s = 'Hello, StackOverflow!'
enc_s,shift = encode_string(s)
dec_s = decode_string(enc_s,shift)
シフトがランダムな場合は、それを引数として渡すことができます:
import random
def shift_char(ch,shift):
if not ch.isalpha():
return ch # return non-alphabetic characters as is
if ch.isupper():
base_a = 'A'
else:
base_a = 'a'
return chr(ord(base_a) + (ord(ch)-ord(base_a)+shift)%26)
def encode_string(s,shift):
return ''.join(shift_char(i,shift) for i in s)
def decode_string(s,shift):
return ''.join(shift_char(i,-shift) for i in s)
# usage
s = 'Hello, StackOverflow!'
shift = random.randint(1,25)
enc_s = encode_string(s,shift)
dec_s = decode_string(enc_s,shift)
またはメソッドを再配置します
import random
def shift_char(ch,shift):
if not ch.isalpha():
return ch # return non-alphabetic characters as is
if ch.isupper():
base_a = 'A'
else:
base_a = 'a'
return chr(ord(base_a) + (ord(ch)-ord(base_a)+shift)%26)
def encode_string(s):
shift = random.randint(1,25)
return ''.join(shift_char(i,shift) for i in s), shift
def decode_string(s,shift):
return ''.join(shift_char(i,-shift) for i in s)
# usage
s = 'Hello, StackOverflow!'
enc_s, shift = encode_string(s)
dec_s = decode_string(enc_s,shift)