تشفير سياج السكك الحديدية - التشفير وفك التشفير
إعطاء رسالة نصية عادية ومفتاح رقمي لتشفير/فك تشفير النص المحدد باستخدام خوارزمية 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، فسيتم إعداد التشفير على النحو التالي:
.'.سيتم إجراء التشفير حسب الصف، أي GSGSEKFREKEOE
فك التشفير
كما رأينا سابقًا، يظل عدد الأعمدة في تشفير سياج السكك الحديدية مساويًا لطول رسالة النص العادي. والمفتاح يتوافق مع عدد القضبان.
- وبالتالي يمكن بناء مصفوفة السكك الحديدية وفقا لذلك. بمجرد حصولنا على المصفوفة، يمكننا معرفة الأماكن التي يجب وضع النصوص فيها (باستخدام نفس طريقة التحرك قطريًا لأعلى ولأسفل بالتناوب).
- ثم نملأ صف النص المشفر بحكمة. بعد ملئها نقوم باجتياز المصفوفة بطريقة متعرجة للحصول على النص الأصلي.
تطبيق:
دع نص التشفير = 'GsGsekfrek eoe' والمفتاح = 3
- عدد الأعمدة في المصفوفة = لين (نص التشفير) = 13
- عدد الصفوف = المفتاح = 3
وبالتالي فإن المصفوفة الأصلية ستكون 3*13، مع وضع علامة على الأماكن التي تحتوي على نص كـ "*" الذي نحصل عليه
* _ _ _ * _ _ _ * _ _ _ *
_ * _ * _ * _ * _ * _ *
_ _ * _ _ _ * _ _ _ * _
C++
يوجد أدناه برنامج لتشفير/فك تشفير الرسالة باستخدام الخوارزمية المذكورة أعلاه.
Java// C++ program to illustrate Rail Fence Cipher // Encryption and Decryption #includeusing 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 ; } Python3// 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 JayC## 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 SomwanshiJavaScriptusing 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 )); } }// 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تعقيد الوقت: يا (صف * عمود)
إنشاء اختبار
المساحة المساعدة: يا (صف * عمود)
مراجع:
https://en.wikipedia.org/wiki/Rail_fence_cipher
هذه المقالة ساهم بها أشوتوش كومار