Rail Fence Cipher - Codering en decodering

Rail Fence Cipher - Codering en decodering

Gegeven een bericht in platte tekst en een numerieke sleutel, kunt u de gegeven tekst coderen/ontcijferen met behulp van het Rail Fence-algoritme. 
Het railhekcijfer (ook wel zigzagcijfer genoemd) is een vorm van transpositiecijfer. Het ontleent zijn naam aan de manier waarop het is gecodeerd. 
Voorbeelden:  

    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

Encryptie

Bij een transpositiecijfer wordt de volgorde van de alfabetten opnieuw gerangschikt om de cijfertekst te verkrijgen. 

  • In het railhekcijfer wordt de platte tekst naar beneden en diagonaal op opeenvolgende rails van een denkbeeldig hek geschreven.
  • Wanneer we de onderrail bereiken, gaan we diagonaal omhoog en na het bereiken van de bovenrail wordt de richting weer veranderd. De alfabetten van het bericht zijn dus zigzagsgewijs geschreven.
  • Nadat elk alfabet is geschreven, worden de afzonderlijke rijen gecombineerd om de cijfertekst te verkrijgen.


Als het bericht bijvoorbeeld 'GeeksforGeeks' is en het aantal rails = 3, wordt de codering voorbereid als: 
 

Spoorhek-algoritme.'.De encryptie zal per rij worden uitgevoerd, d.w.z. GSGSEKFREKEOE


 

Decryptie

Zoals we eerder hebben gezien, blijft het aantal kolommen in de railfence-codering gelijk aan de lengte van een bericht in platte tekst. En de sleutel komt overeen met het aantal rails.
 

  • Daarom kan de railmatrix dienovereenkomstig worden geconstrueerd. Zodra we de matrix hebben, kunnen we uitzoeken op welke plekken de teksten moeten worden geplaatst (door gebruik te maken van dezelfde manier om afwisselend diagonaal op en neer te bewegen).
  • Vervolgens vullen we de cijfertekst rijsgewijs in. Na het invullen doorkruisen we de matrix zigzaggend om de originele tekst te verkrijgen.


Uitvoering: 
Stel dat cipher-text = 'GsGsekfrek eoe' en Key = 3 
 

  • Aantal kolommen in matrix = len(cijfertekst) = 13
  • Aantal rijen = sleutel = 3


Daarom zal de originele matrix 3*13 zijn en nu plaatsen markeren met tekst als '*' die we krijgen 
 

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


Hieronder staat een programma om het bericht te coderen/decoderen met behulp van het bovenstaande algoritme. 
 

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  ));   

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

Tijdcomplexiteit: O(rij * kolom)
Hulpruimte: O(rij * kolom) 
Referenties: 
https://en.wikipedia.org/wiki/Rail_fence_cipher
Dit artikel is bijgedragen door Ashutosh Kumar

 

Quiz maken