アフィン暗号の実装
アフィン暗号は、単一アルファベット置換暗号の一種で、アルファベットの各文字が、単純な数学関数を使用して暗号化された同等の数値にマッピングされ、文字に変換されます。使用されている式は、各文字が別の文字に暗号化され、再度暗号化されることを意味します。つまり、暗号は基本的に、どの文字がどの文字に送信されるかを制御するルールを備えた標準的な置換暗号です。
プロセス全体は、作業モジュロ m (使用されるアルファベットの長さ) に依存します。アフィン暗号では、まずサイズ m のアルファベットの文字が 0 ~ m-1 の範囲の整数にマッピングされます。
アフィン暗号の「鍵」は、a と b と呼ぶ 2 つの数字で構成されます。以下の説明では、26 文字のアルファベット (m = 26) の使用を前提としています。 a は m に対して素であるように選択する必要があります (つまり、 a は m と共通の因数を持たない必要があります)。
暗号化
これは、モジュラー算術を使用して、各平文文字に対応する整数を、暗号文文字に対応する別の整数に変換します。単一文字の暗号化関数は次のとおりです。
E ( x ) = ( a x + b ) mod m modulus m: size of the alphabet a and b: key of the cipher. a must be chosen such that a and m are coprime.
復号化
暗号文を解読するには、暗号文に対して反対 (または逆) の関数を実行して平文を取得する必要があります。もう一度言いますが、最初のステップは、各暗号文文字を整数値に変換することです。復号化関数は、
D ( x ) = a^-1 ( x - b ) mod m a^-1 : modular multiplicative inverse of a modulo m. i.e. it satisfies the equation 1 = a a^-1 mod m .
乗法逆元を求めるには
次のような数値 x を見つける必要があります。
方程式が真となるような数値 x が見つかった場合、x は a の逆数であり、それを a^-1 と呼びます。この方程式を解く最も簡単な方法は、1 から 25 までの数字をそれぞれ検索し、どれが方程式を満たすかを確認することです。
[gxd] = gcd(am); % we can ignore g and d we dont need them x = mod(xm);
ここで x と a を乗算し、その結果を減算すると (mod 26)、答え 1 が得られます。これは単なる逆関数の定義であることを覚えておいてください。つまり、a*x = 1 (mod 26) の場合、x は a の逆関数です (そして a は x の逆関数です)。
例:
実装:
C++ //CPP program to illustrate Affine Cipher #include using namespace std ; //Key values of a and b const int a = 17 ; const int b = 20 ; string encryptMessage ( string msg ) { ///Cipher Text initially empty string cipher = '' ; for ( int i = 0 ; i < msg . length (); i ++ ) { // Avoid space to be encrypted if ( msg [ i ] != ' ' ) /* applying encryption formula ( a x + b ) mod m {here x is msg[i] and m is 26} and added 'A' to bring it in range of ascii alphabet[ 65-90 | A-Z ] */ cipher = cipher + ( char ) (((( a * ( msg [ i ] - 'A' ) ) + b ) % 26 ) + 'A' ); else //else simply append space character cipher += msg [ i ]; } return cipher ; } string decryptCipher ( string cipher ) { string msg = '' ; int a_inv = 0 ; int flag = 0 ; //Find a^-1 (the multiplicative inverse of a //in the group of integers modulo m.) for ( int i = 0 ; i < 26 ; i ++ ) { flag = ( a * i ) % 26 ; //Check if (a*i)%26 == 1 //then i will be the multiplicative inverse of a if ( flag == 1 ) { a_inv = i ; } } for ( int i = 0 ; i < cipher . length (); i ++ ) { if ( cipher [ i ] != ' ' ) /*Applying decryption formula a^-1 ( x - b ) mod m {here x is cipher[i] and m is 26} and added 'A' to bring it in range of ASCII alphabet[ 65-90 | A-Z ] */ msg = msg + ( char ) ((( a_inv * (( cipher [ i ] + 'A' - b )) % 26 )) + 'A' ); else //else simply append space character msg += cipher [ i ]; } return msg ; } //Driver Program int main ( void ) { string msg = 'AFFINE CIPHER' ; //Calling encryption function string cipherText = encryptMessage ( msg ); cout < < 'Encrypted Message is : ' < < cipherText < < endl ; //Calling Decryption function cout < < 'Decrypted Message is: ' < < decryptCipher ( cipherText ); return 0 ; }
Java // Java program to illustrate Affine Cipher class GFG { // Key values of a and b static int a = 17 ; static int b = 20 ; static String encryptMessage ( char [] msg ) { /// Cipher Text initially empty String cipher = '' ; for ( int i = 0 ; i < msg . length ; i ++ ) { // Avoid space to be encrypted /* applying encryption formula ( a x + b ) mod m {here x is msg[i] and m is 26} and added 'A' to bring it in range of ascii alphabet[ 65-90 | A-Z ] */ if ( msg [ i ] != ' ' ) { cipher = cipher + ( char ) (((( a * ( msg [ i ] - 'A' )) + b ) % 26 ) + 'A' ); } else // else simply append space character { cipher += msg [ i ] ; } } return cipher ; } static String decryptCipher ( String cipher ) { String msg = '' ; int a_inv = 0 ; int flag = 0 ; //Find a^-1 (the multiplicative inverse of a //in the group of integers modulo m.) for ( int i = 0 ; i < 26 ; i ++ ) { flag = ( a * i ) % 26 ; // Check if (a*i)%26 == 1 // then i will be the multiplicative inverse of a if ( flag == 1 ) { a_inv = i ; } } for ( int i = 0 ; i < cipher . length (); i ++ ) { /*Applying decryption formula a^-1 ( x - b ) mod m {here x is cipher[i] and m is 26} and added 'A' to bring it in range of ASCII alphabet[ 65-90 | A-Z ] */ if ( cipher . charAt ( i ) != ' ' ) { msg = msg + ( char ) ((( a_inv * (( cipher . charAt ( i ) + 'A' - b )) % 26 )) + 'A' ); } else //else simply append space character { msg += cipher . charAt ( i ); } } return msg ; } // Driver code public static void main ( String [] args ) { String msg = 'AFFINE CIPHER' ; // Calling encryption function String cipherText = encryptMessage ( msg . toCharArray ()); System . out . println ( 'Encrypted Message is : ' + cipherText ); // Calling Decryption function System . out . println ( 'Decrypted Message is: ' + decryptCipher ( cipherText )); } } // This code contributed by Rajput-Ji
Python # Implementation of Affine Cipher in Python # Extended Euclidean Algorithm for finding modular inverse # eg: modinv(7 26) = 15 def egcd ( a b ): x y u v = 0 1 1 0 while a != 0 : q r = b // a b % a m n = x - u * q y - v * q b a x y u v = a r u v m n gcd = b return gcd x y def modinv ( a m ): gcd x y = egcd ( a m ) if gcd != 1 : return None # modular inverse does not exist else : return x % m # affine cipher encryption function # returns the cipher text def affine_encrypt ( text key ): ''' C = (a*P + b) % 26 ''' return '' . join ([ chr ((( key [ 0 ] * ( ord ( t ) - ord ( 'A' )) + key [ 1 ] ) % 26 ) + ord ( 'A' )) for t in text . upper () . replace ( ' ' '' ) ]) # affine cipher decryption function # returns original text def affine_decrypt ( cipher key ): ''' P = (a^-1 * (C - b)) % 26 ''' return '' . join ([ chr ((( modinv ( key [ 0 ] 26 ) * ( ord ( c ) - ord ( 'A' ) - key [ 1 ])) % 26 ) + ord ( 'A' )) for c in cipher ]) # Driver Code to test the above functions def main (): # declaring text and key text = 'AFFINE CIPHER' key = [ 17 20 ] # calling encryption function affine_encrypted_text = affine_encrypt ( text key ) print ( 'Encrypted Text: {} ' . format ( affine_encrypted_text )) # calling decryption function print ( 'Decrypted Text: {} ' . format ( affine_decrypt ( affine_encrypted_text key ) )) if __name__ == '__main__' : main () # This code is contributed by # Bhushan Borole
C# // C# program to illustrate Affine Cipher using System ; class GFG { // Key values of a and b static int a = 17 ; static int b = 20 ; static String encryptMessage ( char [] msg ) { /// Cipher Text initially empty String cipher = '' ; for ( int i = 0 ; i < msg . Length ; i ++ ) { // Avoid space to be encrypted /* applying encryption formula ( a x + b ) mod m {here x is msg[i] and m is 26} and added 'A' to bring it in range of ascii alphabet[ 65-90 | A-Z ] */ if ( msg [ i ] != ' ' ) { cipher = cipher + ( char ) (((( a * ( msg [ i ] - 'A' )) + b ) % 26 ) + 'A' ); } else // else simply append space character { cipher += msg [ i ]; } } return cipher ; } static String decryptCipher ( String cipher ) { String msg = '' ; int a_inv = 0 ; int flag = 0 ; //Find a^-1 (the multiplicative inverse of a //in the group of integers modulo m.) for ( int i = 0 ; i < 26 ; i ++ ) { flag = ( a * i ) % 26 ; // Check if (a*i)%26 == 1 // then i will be the multiplicative inverse of a if ( flag == 1 ) { a_inv = i ; } } for ( int i = 0 ; i < cipher . Length ; i ++ ) { /*Applying decryption formula a^-1 ( x - b ) mod m {here x is cipher[i] and m is 26} and added 'A' to bring it in range of ASCII alphabet[ 65-90 | A-Z ] */ if ( cipher [ i ] != ' ' ) { msg = msg + ( char ) ((( a_inv * (( cipher [ i ] + 'A' - b )) % 26 )) + 'A' ); } else //else simply append space character { msg += cipher [ i ]; } } return msg ; } // Driver code public static void Main ( String [] args ) { String msg = 'AFFINE CIPHER' ; // Calling encryption function String cipherText = encryptMessage ( msg . ToCharArray ()); Console . WriteLine ( 'Encrypted Message is : ' + cipherText ); // Calling Decryption function Console . WriteLine ( 'Decrypted Message is: ' + decryptCipher ( cipherText )); } } /* This code contributed by PrinciRaj1992 */
JavaScript //Javascript program to illustrate Affine Cipher //Key values of a and b let a = 17 ; let b = 20 ; function encryptMessage ( msg ) { ///Cipher Text initially empty let cipher = '' ; for ( let i = 0 ; i < msg . length ; i ++ ) { // Avoid space to be encrypted if ( msg [ i ] != ' ' ) /* applying encryption formula ( a x + b ) mod m {here x is msg[i] and m is 26} and added 'A' to bring it in range of ascii alphabet[ 65-90 | A-Z ] */ cipher = cipher + String . fromCharCode (((( a * ( msg [ i ]. charCodeAt ( 0 ) - 65 ) ) + b ) % 26 ) + 65 ); else //else simply append space character cipher += msg [ i ]; } return cipher ; } function decryptCipher ( cipher ) { let msg = '' ; let a_inv = 0 ; let flag = 0 ; //Find a^-1 (the multiplicative inverse of a //in the group of integers modulo m.) for ( let i = 0 ; i < 26 ; i ++ ) { flag = ( a * i ) % 26 ; //Check if (a*i)%26 == 1 //then i will be the multiplicative inverse of a if ( flag == 1 ) { a_inv = i ; } } for ( let i = 0 ; i < cipher . length ; i ++ ) { if ( cipher [ i ] != ' ' ) /*Applying decryption formula a^-1 ( x - b ) mod m {here x is cipher[i] and m is 26} and added 'A' to bring it in range of ASCII alphabet[ 65-90 | A-Z ] */ msg = msg + String . fromCharCode ((( a_inv * (( cipher [ i ]. charCodeAt ( 0 ) + 65 - b )) % 26 )) + 65 ); else //else simply append space character msg += cipher [ i ]; } return msg ; } //Driver Program let msg = 'AFFINE CIPHER' ; //Calling encryption function let cipherText = encryptMessage ( msg ); console . log ( 'Encrypted Message is : ' + cipherText ); //Calling Decryption function console . log ( 'Decrypted Message is: ' + decryptCipher ( cipherText )); // The code is contributed by Arushi Jindal.
出力
Encrypted Message is : UBBAHK CAPJKX Decrypted Message is: AFFINE CIPHER
クイズの作成