Podano sporočilo z navadnim besedilom in numerični ključ šifrira/dešifrira dano besedilo z uporabo algoritma Rail Fence.
Šifra tirne ograje (imenovana tudi cikcak šifra) je oblika transpozicijske šifre. Ime je dobil po načinu, na katerega je kodiran.
Primeri:
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
Šifriranje
V transpozicijski šifri se vrstni red abecede preuredi, da se dobi šifrirano besedilo.
- V šifri tirne ograje je golo besedilo zapisano navzdol in diagonalno na zaporednih tirnicah namišljene ograje.
- Ko dosežemo spodnjo tirnico, se premikamo navzgor diagonalno, ko dosežemo zgornjo tirnico, se smer spet spremeni. Tako so abecede sporočila napisane v cik-cak obliki.
- Ko je vsaka abeceda zapisana, se posamezne vrstice združijo, da dobimo šifrirano besedilo.
Na primer, če je sporočilo 'GeeksforGeeks' in je število tirnic = 3, je šifra pripravljena kot:
Dešifriranje
Kot smo že videli, število stolpcev v šifri ograje ostane enako dolžini sporočila z navadnim besedilom. In ključ ustreza številu tirnic.
- Zato je mogoče ustrezno izdelati matriko tirnic. Ko imamo matriko, lahko ugotovimo mesta, kamor naj bodo besedila postavljena (z uporabo enakega načina premikanja diagonalno gor in dol izmenično).
- Nato zapolnimo vrstico s šifriranim besedilom. Po polnjenju prečkamo matrico v cik-cak načinu, da dobimo izvirno besedilo.
Izvedba:
Naj bo šifrirano besedilo = 'GsGsekfrek eoe' in ključ = 3
- Število stolpcev v matriki = len(šifrirano besedilo) = 13
- Število vrstic = ključ = 3
Zato bo prvotna matrika velikosti 3*13, kar zdaj označuje mesta z besedilom kot '*'
pogojni operator v Javi
* _ _ _ * _ _ _ * _ _ _ *
_ * _ * _ * _ * _ * _ *
_ _ * _ _ _ * _ _ _ * _
Spodaj je program za šifriranje/dešifriranje sporočila z uporabo zgornjega algoritma.
// 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));
Izhod
atc toctaka ne GsGsekfrek eoe dnhaweedtees alf tl GeeksforGeeks attack at once defend the east wall
Časovna zapletenost: O(vrstica * stolpec)
Pomožni prostor: O(vrstica * stolpec)
Reference:
https://en.wikipedia.org/wiki/Rail_fence_cipher
Ta članek je prispeval Ašutoš Kumar