logo

レールフェンス暗号 - 暗号化と復号化

プレーンテキスト メッセージと数値キーを指定すると、Rail Fence アルゴリズムを使用して指定されたテキストを暗号化/復号化します。 
レールフェンス暗号 (ジグザグ暗号とも呼ばれる) は、転置暗号の一種です。その名前は、エンコード方法に由来しています。 
例:  

    Encryption     
Input : 'GeeksforGeeks '
Key = 3
Output : GsGsekfrek eoe
Decryption
Input : GsGsekfrek eoe
Key = 3
Output : 'GeeksforGeeks '

Encryption
Input : 'defend the east wall'
Key = 3
Output : dnhaweedtees alf tl
Decryption
Input : dnhaweedtees alf tl
Key = 3
Output : defend the east wall

Encryption
Input : 'attack at once'
Key = 2
Output : atc toctaka ne
Decryption
Input : 'atc toctaka ne'
Key = 2
Output : attack at once

暗号化

転置暗号では、アルファベットの順序を並べ替えて暗号文を取得します。 



  • レールフェンス暗号では、平文は架空のフェンスの連続するレール上に斜め下向きに書かれます。
  • 下のレールに到達すると、斜めに上向きに移動し、上のレールに到達した後、再び方向が変わります。したがって、メッセージのアルファベットはジグザグに書かれます。
  • 各アルファベットが書かれた後、個々の行が結合されて暗号文が得られます。


たとえば、メッセージが「GeeksforGeeks」でレール数 = 3 の場合、暗号は次のように準備されます。 
 

レールフェンスアルゴリズム' src='//techcodeview.com/img/dsa/69/rail-fence-cipher-encryption-and-decryption.webp' title=.'.暗号化は行単位で行われます。つまり、GSGSEKFREKEOE


 

復号化

前に見たように、レール フェンス暗号の列数は平文メッセージの長さと同じままです。そしてキーはレールの数に対応します。
 

  • したがって、それに応じてレール マトリックスを構築できます。マトリックスを取得したら、テキストを配置する場所を把握できます (同じ方法で斜めに上下に移動することもできます)。
  • 次に、暗号文を行ごとに埋めていきます。それを埋めた後、マトリックスをジグザグに走査して元のテキストを取得します。


実装: 
cipher-text = 'GsGsekfrek eoe'、Key = 3 とします。 
 

  • 行列の列数 = len(暗号文) = 13
  • 行数 = キー = 3


したがって、元の行列は 3*13 になり、テキストのある場所は「*」としてマークされます。 
 

* _ _ _ * _ _ _ * _ _ _ *  
_ * _ * _ * _ * _ * _ *
_ _ * _ _ _ * _ _ _ * _


以下は、上記のアルゴリズムを使用してメッセージを暗号化/復号化するプログラムです。 
 

C++
// C++ program to illustrate Rail Fence Cipher // Encryption and Decryption #include    using namespace std; // function to encrypt a message string encryptRailFence(string text int key) {  // create the matrix to cipher plain text  // key = rows  length(text) = columns  char rail[key][(text.length())];  // filling the rail matrix to distinguish filled  // spaces from blank ones  for (int i=0; i < key; i++)  for (int j = 0; j < text.length(); j++)  rail[i][j] = 'n';  // to find the direction  bool dir_down = false;  int row = 0 col = 0;  for (int i=0; i < text.length(); i++)  {  // check the direction of flow  // reverse the direction if we've just  // filled the top or bottom rail  if (row == 0 || row == key-1)  dir_down = !dir_down;  // fill the corresponding alphabet  rail[row][col++] = text[i];  // find the next row using direction flag  dir_down?row++ : row--;  }  //now we can construct the cipher using the rail matrix  string result;  for (int i=0; i < key; i++)  for (int j=0; j < text.length(); j++)  if (rail[i][j]!='n')  result.push_back(rail[i][j]);  return result; } // This function receives cipher-text and key // and returns the original text after decryption string decryptRailFence(string cipher int key) {  // create the matrix to cipher plain text  // key = rows  length(text) = columns  char rail[key][cipher.length()];  // filling the rail matrix to distinguish filled  // spaces from blank ones  for (int i=0; i < key; i++)  for (int j=0; j < cipher.length(); j++)  rail[i][j] = 'n';  // to find the direction  bool dir_down;  int row = 0 col = 0;  // mark the places with '*'  for (int i=0; i < cipher.length(); i++)  {  // check the direction of flow  if (row == 0)  dir_down = true;  if (row == key-1)  dir_down = false;  // place the marker  rail[row][col++] = '*';  // find the next row using direction flag  dir_down?row++ : row--;  }  // now we can construct the fill the rail matrix  int index = 0;  for (int i=0; i<key; i++)  for (int j=0; j<cipher.length(); j++)  if (rail[i][j] == '*' && index<cipher.length())  rail[i][j] = cipher[index++];  // now read the matrix in zig-zag manner to construct  // the resultant text  string result;  row = 0 col = 0;  for (int i=0; i< cipher.length(); i++)  {  // check the direction of flow  if (row == 0)  dir_down = true;  if (row == key-1)  dir_down = false;  // place the marker  if (rail[row][col] != '*')  result.push_back(rail[row][col++]);  // find the next row using direction flag  dir_down?row++: row--;  }  return result; } //driver program to check the above functions int main() {  cout << encryptRailFence('attack at once' 2) << endl;  cout << encryptRailFence('GeeksforGeeks ' 3) << endl;  cout << encryptRailFence('defend the east wall' 3) << endl;  //Now decryption of the same cipher-text  cout << decryptRailFence('GsGsekfrek eoe'3) << endl;  cout << decryptRailFence('atc toctaka ne'2) << endl;  cout << decryptRailFence('dnhaweedtees alf tl'3) << endl;  return 0; } 
Java
// Java program to illustrate Rail Fence Cipher // Encryption and Decryption import java.util.Arrays; class RailFence {  // function to encrypt a message  public static String encryptRailFence(String text  int key)  {  // create the matrix to cipher plain text  // key = rows  length(text) = columns  char[][] rail = new char[key][text.length()];  // filling the rail matrix to distinguish filled  // spaces from blank ones  for (int i = 0; i < key; i++)  Arrays.fill(rail[i] 'n');  boolean dirDown = false;  int row = 0 col = 0;  for (int i = 0; i < text.length(); i++) {  // check the direction of flow  // reverse the direction if we've just  // filled the top or bottom rail  if (row == 0 || row == key - 1)  dirDown = !dirDown;  // fill the corresponding alphabet  rail[row][col++] = text.charAt(i);  // find the next row using direction flag  if (dirDown)  row++;  else  row--;  }  // now we can construct the cipher using the rail  // matrix  StringBuilder result = new StringBuilder();  for (int i = 0; i < key; i++)  for (int j = 0; j < text.length(); j++)  if (rail[i][j] != 'n')  result.append(rail[i][j]);  return result.toString();  }  // This function receives cipher-text and key  // and returns the original text after decryption  public static String decryptRailFence(String cipher  int key)  {  // create the matrix to cipher plain text  // key = rows  length(text) = columns  char[][] rail = new char[key][cipher.length()];  // filling the rail matrix to distinguish filled  // spaces from blank ones  for (int i = 0; i < key; i++)  Arrays.fill(rail[i] 'n');  // to find the direction  boolean dirDown = true;  int row = 0 col = 0;  // mark the places with '*'  for (int i = 0; i < cipher.length(); i++) {  // check the direction of flow  if (row == 0)  dirDown = true;  if (row == key - 1)  dirDown = false;  // place the marker  rail[row][col++] = '*';  // find the next row using direction flag  if (dirDown)  row++;  else  row--;  }  // now we can construct the fill the rail matrix  int index = 0;  for (int i = 0; i < key; i++)  for (int j = 0; j < cipher.length(); j++)  if (rail[i][j] == '*'  && index < cipher.length())  rail[i][j] = cipher.charAt(index++);  StringBuilder result = new StringBuilder();  row = 0;  col = 0;  for (int i = 0; i < cipher.length(); i++) {  // check the direction of flow  if (row == 0)  dirDown = true;  if (row == key - 1)  dirDown = false;  // place the marker  if (rail[row][col] != '*')  result.append(rail[row][col++]);  // find the next row using direction flag  if (dirDown)  row++;  else  row--;  }  return result.toString();  }  // driver program to check the above functions  public static void main(String[] args)  {  // Encryption  System.out.println('Encrypted Message: ');  System.out.println(  encryptRailFence('attack at once' 2));  System.out.println(  encryptRailFence('GeeksforGeeks ' 3));  System.out.println(  encryptRailFence('defend the east wall' 3));  // Now decryption of the same cipher-text  System.out.println('nDecrypted Message: ');  System.out.println(  decryptRailFence('atc toctaka ne' 2));  System.out.println(  decryptRailFence('GsGsekfrek eoe' 3));  System.out.println(  decryptRailFence('dnhaweedtees alf tl' 3));  } } // This code is contributed by Jay 
Python3
# Python3 program to illustrate # Rail Fence Cipher Encryption # and Decryption # function to encrypt a message def encryptRailFence(text key): # create the matrix to cipher # plain text key = rows  # length(text) = columns # filling the rail matrix # to distinguish filled # spaces from blank ones rail = [['n' for i in range(len(text))] for j in range(key)] # to find the direction dir_down = False row col = 0 0 for i in range(len(text)): # check the direction of flow # reverse the direction if we've just # filled the top or bottom rail if (row == 0) or (row == key - 1): dir_down = not dir_down # fill the corresponding alphabet rail[row][col] = text[i] col += 1 # find the next row using # direction flag if dir_down: row += 1 else: row -= 1 # now we can construct the cipher # using the rail matrix result = [] for i in range(key): for j in range(len(text)): if rail[i][j] != 'n': result.append(rail[i][j]) return('' . join(result)) # This function receives cipher-text # and key and returns the original # text after decryption def decryptRailFence(cipher key): # create the matrix to cipher # plain text key = rows  # length(text) = columns # filling the rail matrix to # distinguish filled spaces # from blank ones rail = [['n' for i in range(len(cipher))] for j in range(key)] # to find the direction dir_down = None row col = 0 0 # mark the places with '*' for i in range(len(cipher)): if row == 0: dir_down = True if row == key - 1: dir_down = False # place the marker rail[row][col] = '*' col += 1 # find the next row # using direction flag if dir_down: row += 1 else: row -= 1 # now we can construct the # fill the rail matrix index = 0 for i in range(key): for j in range(len(cipher)): if ((rail[i][j] == '*') and (index < len(cipher))): rail[i][j] = cipher[index] index += 1 # now read the matrix in # zig-zag manner to construct # the resultant text result = [] row col = 0 0 for i in range(len(cipher)): # check the direction of flow if row == 0: dir_down = True if row == key-1: dir_down = False # place the marker if (rail[row][col] != '*'): result.append(rail[row][col]) col += 1 # find the next row using # direction flag if dir_down: row += 1 else: row -= 1 return(''.join(result)) # Driver code if __name__ == '__main__': print(encryptRailFence('attack at once' 2)) print(encryptRailFence('GeeksforGeeks ' 3)) print(encryptRailFence('defend the east wall' 3)) # Now decryption of the # same cipher-text print(decryptRailFence('GsGsekfrek eoe' 3)) print(decryptRailFence('atc toctaka ne' 2)) print(decryptRailFence('dnhaweedtees alf tl' 3)) # This code is contributed # by Pratik Somwanshi 
C#
using System; class GFG_RailFence {  // function to encrypt a message  public static string EncryptRailFence(string text int key) {  // create the matrix to cipher plain text  // key = rows length(text) = columns  char[] rail = new char[key text.Length];  // filling the rail matrix to distinguish filled  // spaces from blank ones  for (int i = 0; i < key; i++)  for (int j = 0; j < text.Length; j++)  rail[i j] = 'n';  bool dirDown = false;  int row = 0 col = 0;  for (int i = 0; i < text.Length; i++) {  // check the direction of flow  // reverse the direction if we've just  // filled the top or bottom rail  if (row == 0 || row == key - 1)  dirDown = !dirDown;  // fill the corresponding alphabet  rail[row col++] = text[i];  // find the next row using direction flag  if (dirDown)  row++;  else  row--;  }  // now we can construct the cipher using the rail  // matrix  string result = '';  for (int i = 0; i < key; i++)  for (int j = 0; j < text.Length; j++)  if (rail[i j] != 'n')  result += rail[i j];  return result;  }  // This function receives cipher-text and key  // and returns the original text after decryption  public static string DecryptRailFence(string cipher int key) {  // create the matrix to cipher plain text  // key = rows length(text) = columns  // create the matrix to cipher plain text  // key = rows  length(text) = columns  char[] rail = new char[key cipher.Length];  // filling the rail matrix to distinguish filled  // spaces from blank ones  for (int i = 0; i < key; i++)  for (int j = 0; j < cipher.Length; j++)  rail[i j] = 'n';  // to find the direction  bool dirDown = true;  int row = 0 col = 0;  // mark the places with '*'  for (int i = 0; i < cipher.Length; i++) {  // check the direction of flow  if (row == 0)  dirDown = true;  if (row == key - 1)  dirDown = false;  // place the marker  rail[row col++] = '*';  // find the next row using direction flag  if (dirDown)  row++;  else  row--;  }  // now we can construct the fill the rail matrix  int index = 0;  for (int i = 0; i < key; i++)  for (int j = 0; j < cipher.Length; j++)  if (rail[i j] == '*' && index < cipher.Length)  rail[i j] = cipher[index++];  // create the result string  string result = '';  row = 0;  col = 0;  // iterate through the rail matrix  for (int i = 0; i < cipher.Length; i++) {  // check the direction of flow  if (row == 0)  dirDown = true;  if (row == key - 1)  dirDown = false;  // place the marker  if (rail[row col] != '*')  result += rail[row col++];  // find the next row using direction flag  if (dirDown)  row++;  else  row--;  }  return result;  }  // driver program to check the above functions  public static void Main() {  // Encryption  Console.WriteLine('Encrypted Message: ');  Console.WriteLine(EncryptRailFence('attack at once' 2));  Console.WriteLine(  EncryptRailFence('GeeksforGeeks ' 3));  Console.WriteLine(  EncryptRailFence('defend the east wall' 3));  // Now decryption of the same cipher-text  Console.WriteLine('nDecrypted Message: ');  Console.WriteLine(  DecryptRailFence('atc toctaka ne' 2));  Console.WriteLine(  DecryptRailFence('GsGsekfrek eoe' 3));  Console.WriteLine(  DecryptRailFence('dnhaweedtees alf tl' 3));  } } 
JavaScript
// function to encrypt a message function encryptRailFence(text key) {  // create the matrix to cipher plain text  // key = rows  text.length = columns  let rail = new Array(key).fill().map(() => new Array(text.length).fill('n'));  // filling the rail matrix to distinguish filled  // spaces from blank ones  let dir_down = false;  let row = 0 col = 0;  for (let i = 0; i < text.length; i++) {  // check the direction of flow  // reverse the direction if we've just  // filled the top or bottom rail  if (row == 0 || row == key - 1) dir_down = !dir_down;  // fill the corresponding alphabet  rail[row][col++] = text[i];  // find the next row using direction flag  dir_down ? row++ : row--;  }  // now we can construct the cipher using the rail matrix  let result = '';  for (let i = 0; i < key; i++)  for (let j = 0; j < text.length; j++)  if (rail[i][j] != 'n') result += rail[i][j];  return result; } // function to decrypt a message function decryptRailFence(cipher key) {  // create the matrix to cipher plain text  // key = rows  text.length = columns  let rail = new Array(key).fill().map(() => new Array(cipher.length).fill('n'));  // filling the rail matrix to mark the places with '*'  let dir_down = false;  let row = 0 col = 0;  for (let i = 0; i < cipher.length; i++) {  // check the direction of flow  if (row == 0) dir_down = true;  if (row == key - 1) dir_down = false;  // place the marker  rail[row][col++] = '*';  // find the next row using direction flag  dir_down ? row++ : row--;  }  // now we can construct the rail matrix by filling the marked places with cipher text  let index = 0;  for (let i = 0; i < key; i++)  for (let j = 0; j < cipher.length; j++)  if (rail[i][j] == '*' && index < cipher.length) rail[i][j] = cipher[index++];  // now read the matrix in zig-zag manner to construct the resultant text  let result = '';  row = 0 col = 0;  for (let i = 0; i < cipher.length; i++) {  // check the direction of flow  if (row == 0) dir_down = true;  if (row == key - 1) dir_down = false;  // place the marker  if (rail[row][col] != '*') result += rail[row][col++];  // find the next row using direction flag  dir_down ? row++ : row--;  }  return result; } // driver program to check the above functions  // Encryption console.log(encryptRailFence('attack at once' 2));  console.log(encryptRailFence('GeeksforGeeks' 3));  console.log(encryptRailFence('defend the east wall' 3)); // Now decryption of the same cipher-text console.log(decryptRailFence('GsGsekfrek eoe' 3)); console.log(decryptRailFence('atc toctaka ne' 2)); console.log(decryptRailFence('dnhaweedtees alf tl' 3)); 

出力
atc toctaka ne GsGsekfrek eoe dnhaweedtees alf tl GeeksforGeeks attack at once defend the east wall 

時間計算量: O(行 * 列)
補助スペース: O(行 * 列) 
参考文献: 
https://en.wikipedia.org/wiki/Rail_fence_cipher
この記事は次の寄稿者です アシュトシュ・クマール

 

クイズの作成