Pages

Friday, October 16, 2015

Railfence Columnar Cipher

This is the combination of Rail fence Cipher with Columnar implementation..



  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
import java.util.*;

public class RFwithColumnar {
    public static void main(String[] args) {

        String text = "IF YOU CAN READ THIS YOU ARE GENIUS";
        String key = "HACK";

        String enc = RFCEncryption(text, key);

        System.out.println(enc);
    }

    public static String RFCEncryption(String text, String keytext) {
        int[] arrange = arrangeKey(keytext);

        int key = arrange.length;
        int lentext = text.length();

        int move = 1;
        int count = 0;
        String[][] rfp = new String[key][lentext];

        // arrange dot fence
        for (int x = 0; x < rfp.length; x++) {
            for (int y = 0; y < rfp[x].length; y++) {
                rfp[x][y] = ".";
            }
        }

        // formatting according fence rails
        for (int i = 0; i < lentext; i++) {
            if ((move % 2) != 0) {
                rfp[count][i] = "" + text.charAt(i);
                if (count == (key - 1)) {
                    move = 2;
                    count = (key - 2);
                } else
                    count++;
            } else if ((move % 2) == 0) {
                rfp[count][i] = "" + text.charAt(i);
                if (count == 0) {
                    move = 1;
                    count = 1;
                } else
                    count--;
            }
        }

        //replace any white space with X or random
        for (int x = 0; x < rfp.length; x++) {
            for (int y = 0; y < rfp[x].length; y++) {
                if (rfp[x][y].equals(" "))
                    rfp[x][y] = ""+Character.toUpperCase(RandomAlpha());
            }
        }

        // display
        System.out.println();
        for (int i = 0; i < rfp.length; i++) {
            for (int u = 0; u < rfp[i].length; u++) {
                System.out.print(rfp[i][u] + " ");
            }
            System.out.println();
        }
        System.out.println();


        StringBuilder cb = new StringBuilder();
        //encode string from fence
        for (int x = 0; x < key; x++) {
            for (int y = 0; y < key; y++) {
                if (x == arrange[y]) {
                    for (int u = 0; u < lentext; u++) {
                        if (!".".equals(rfp[y][u])) {
                            cb.append(rfp[y][u]);
                        }
                    }
                }
            }
        }
        return "" + cb;
    }
    
    public static int[] arrangeKey(String key) {
        //arrange position of grid
        String[] keys = key.split("");
        Arrays.sort(keys);
        int[] num = new int[key.length()];
        for (int x = 0; x < keys.length; x++) {
            for (int y = 0; y < key.length(); y++) {
                if (keys[x].equals(key.charAt(y) + "")) {
                    num[y] = x;
                    break;
                }
            }
        }
        System.out.println(Arrays.toString(num));
        return num;
    }
    
    public static char RandomAlpha() {
        //generate random alpha for null space
        Random r = new Random();
        return (char)(r.nextInt(26) + 'a');
    }
}

Sunday, October 11, 2015

Scratch Programming

Scratch programming is very interesting after joining Volunteer Digital Tech @ Schools at Knowledge Development Center (KDC) under MDeC and ARUS. Scratch is an IDE where just using your creativity to drag and drop any block or function to match any of your animation you want. Just like Greenfoot programming but scratch is focus more on kids where there is no code involved and easy to the kids how to create animation they want. 

What is scratch programming?

Scratch is a programming language and an online community where children can program and share interactive media such as stories, games, and animation with people from all over the world. As children create with Scratch, they learn to think creatively, work collaboratively, and reason systematically.

Below is the example of block in scratch programming


Below is the examples of what i manage to do with scratch programming. I am using a lot of blocks just to create a pong games..



This is the examples where people share their animation --> https://scratch.mit.edu

During our training..this is what we do so far --> https://scratch.mit.edu/studios/1599700/

Have the best luck!..

Friday, October 9, 2015

Random alphabet character with no duplicate


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
   public static String RandomAlpha(int len){
      Random r = new Random();
      String key = "";
      for(int x=0;x<len;x++)
         key = key + (char) (r.nextInt(26) + 'A');
      return key;
   }
   
   public static String RandomAlphaNoDuplicate(int len){
      Random r = new Random();
      String key = "";
      for (int i = 0; i < len;) {
          char c = (char) (r.nextInt(26) + 'A');
          if(!key.toString().contains(""+c)){
             key = key + c;
             i++;
          }
      }      
      return key;
   }

Thursday, October 8, 2015

Kamasutra Cipher

One of the earliest descriptions of encryption by substitution appears in the Kama-sutra, a text written in the 4th century AD by the Brahmin scholar Vatsyayana, but based on manuscripts dating back to the 4th century BC. The Kama-sutra recommends that women should study 64 arts, including cooking, dressing, massage and the preparation of perfumes. The list also includes some less obvious arts, including conjuring, chess, bookbinding and carpentry. Number 45 on the list is mlecchita-vikalpa, the art of secret writing, advocated in order to help women conceal the details of their liaisons. One of the recommended techniques involves randomly pairing letters of the alphabet, and then substituting each letter in the original message with its partner.4

How it work
The kamasutra generate list of 26 alphabet with no duplicate. Then divide by 2 row. Find for each letter of message text in table and choose the opposite of the letter

for example:
Key = G H A J R I O B E S Q C L F V Z T Y K M X W N U D P

divide by 2 rows

G H A J R I O B E S Q C L
F V Z T Y K M X W N U D P

Given String = KAMASUTRA

K is at 2nd row and 5th column. Get the opposite of K that is I. Do each letter until the end

Cipher : IZOZNQJYZ

To decyrpt the cipher, use the table with same random list of 26 alphabet. Without the key is difficult to decrypt because of  26! = 403,291,461,000,000,000,000,000,000 = 403 septilion of combination of key can be produce uniquely.




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
   authors by hafiq
   
   Kamasutra Cipher and decrytion
      
   any expert can advise me to improve this code...tq..
*/
import java.util.*;

public class KSCipher{
   public static void main(String[] args){
      String text = "KAMA SUTRA CIPHER";
      String key  = RandomAlphaNoDuplicate(26);
      
      String enc = KSutra(text,key);
      System.out.println("Encryption: "+ enc);
      String dec = KSutra(enc,key);
      System.out.println("Decryption: "+ dec);
   }
   
   public static String RandomAlphaNoDuplicate(int len){
      Random r = new Random();
      String key = "";
      for (int i = 0; i < len;) {
          char c = (char) (r.nextInt(26) + 'A');
          if(!key.toString().contains(""+c)){
             key = key + c;
             i++;
          }
      }      
      return key;
   }
   
   public static String KSutra(String text,String key){
      int keyLen = key.length()/2;
      
      // arrange random key
      char[][] keyRow = new char[2][keyLen];
      int count=0;
      for(int x=0;x<2;x++){
         for(int y=0;y<keyLen;y++){
            keyRow[x][y] = key.charAt(count);
            System.out.print(keyRow[x][y]+" ");
            count++;
         }
         System.out.println();
      }
      
      String sb = "";
      
      count=0;
      for(int x=0;x<text.length();x++){
         for(int y=0;y<2;y++){
            for(int z=0;z<keyLen;z++){
               if(y == 0){
                  if(text.charAt(x) == keyRow[y][z])
                     sb += keyRow[y+1][z];
               }
               else if (y == 1){
                  if(text.charAt(x) == keyRow[y][z])
                     sb += keyRow[y-1][z];
               }
            }
         }
         if(text.charAt(x) == ' ')
            sb += text.charAt(x);
      }
      
      return sb;
   }
}

One-Time Pad Cipher

In cryptography, the one-time pad (OTP) is an encryption technique that cannot be cracked if used correctly. It was invented near the end of WWI by Gilbert Vernam and Joseph Mauborgne in the US. It was mathematically proven unbreakable by Claude Shannon, probably during WWII, his work was first published in the late 1940s.

How it work

In this technique, a plaintext is paired with a random secret key (also referred to as a one-time pad). Then, each bit or character of the plaintext is encrypted by combining it with the corresponding bit or character from the pad using modular addition. If the key is truly random, is at least as long as the plaintext, is never reused in whole or in part, and is kept completely secret, then the resulting ciphertext will be impossible to decrypt or break.

Are one-time pads really unbreakable?

Yes. But only if used properly. A one-time pad must be truly random data and must be kept secure in order to be unbreakable. Consider if the one-time pad is used to encode the word "otter." If an attacker tries to brute force "guess" the contents of the pad, the message will "decrypt" into every possible combination of 6 characters (e.g.: "lemur." "badger" etc..) Since the pad is truly random there are no statistical methods that the attacker can hope to use to infer which combination is correct.

Below is the example of one time cipher work



In this example, the technique is to combine the key and the message using modular addition. The numerical values of corresponding message and key letters are added together, modulo 26 (%26). So, if key randomly begins with "XMCKL" and the message is "HELLO", then the coding would be done as follows:

Calculation:

A B C D E F G H I J K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

H + X = E because 7 + 23 = 30 % 26 = 4 is E
E + M = Q because 4 + 12 = 16 % 26 = 16 is Q
so on..


      H       E       L       L       O  message
   7 (H)   4 (E)  11 (L)  11 (L)  14 (O) message
+ 23 (X)  12 (M)   2 (C)  10 (K)  11 (L) key
= 30      16      13      21      25     message + key
=  4 (E)  16 (Q)  13 (N)  21 (V)  25 (Z) message + key (mod 26)
      E       Q       N       V       Z  → ciphertext


Ciphertext = EQNVZ
This is similar with caesar cipher. This simply means that if the computations "go past" Z, the sequence starts again at A.

Now, Let's Decrypt

The ciphertext is "EQNVZ". Use the matching key and the same process but in reverse to obtain the plaintext. Here the key is subtracted from the ciphertext again using modular arithmetic:

       E       Q       N       V       Z  ciphertext
    4 (E)  16 (Q)  13 (N)  21 (V)  25 (Z) ciphertext
-  23 (X)  12 (M)   2 (C)  10 (K)  11 (L) key
= -19       4      11      11      14     ciphertext – key
=   7 (H)   4 (E)  11 (L)  11 (L)  14 (O) ciphertext – key (mod 26)
       H       E       L       L       O  → message

Text = HELLO

However, it is difficult to ensure that the key is actually random is used only once, never becomes known to the opposition and is completely destroyed after use. The auxiliary parts of a software one-time pad implementation present real challenges: secure handling/transmission of plaintext truly random keys and one-time-only use of the key.

Wednesday, October 7, 2015

Generate list of Permutation of N length



In cryptography, a brute-force attack, or exhaustive key search, is a cryptanalytic attack that can, in theory, be used against any encrypted data.

Brute force attacks work by calculating every possible combination that could make up a password and testing it to see if it is the correct password. As the password’s length increases, the amount of time, on average, to find the correct password increases exponentially. This means short passwords can usually be discovered quite quickly, but longer passwords may take decades.

String list is A-z. Length is 26 + 26 = 52 character.

the combination of 5 character is

52 * 52 * 52 * 52 *52 = 52^5 = 380204032 combination !!!


Below is the example of brute force.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.*;
/*
   modified by hafiq
   Brute force list ex: a..aaab..aaaaaaC....
   any expert can advise me to improve this code...tq..
*/
public class Bruteforce
{
  public static void main(String[] args){
      String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
      int max = 4; //limit length
      generate(str.toCharArray(),max);
  }
  public static void generate(char[] input,int max) {
    char[] result = new char[input.length];
    int[] index = new int[input.length];

    // initialize the arrays.
    Arrays.fill(result, 0, result.length, input[0]);
    Arrays.fill(index,  0, index.length, 0);

    // loop over the output lengths.
    for( int length = 1; length <= max; length++ ) {
      int update = 0;
      
      while(update != -1){
        System.out.println(new String(result, 0, length));

        // update values that need to reset.
        for(update = length-1;
            update != -1 && ++index[update] == input.length;
            result[update] = input[0], index[update] = 0, update--);

        // update the character that is not resetting, if valid
        if( update != -1 ) 
            result[update] = input[index[update]];
      } 
    }
  }
}

Vigenere cipher

The Vigenère cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.

This cipher is similar with caesar cipher but different in term of shifting. The Vigenère cipher consists of several Caesar ciphers in sequence with different shift values. To encrypt, a table of alphabets can be used called Vigenère table. It consists of the alphabet written out 26 times in different rows, each alphabet shifted cyclically to the left compared to the previous alphabet, corresponding to the 26 possible Caesar ciphers.

Vigenere table
For example, suppose that the plaintext to be encrypted is:

Let Encrypt the text

Given string : ATTACKATDAWN

For the key, for example "LEMON". Repeat the word "LEMON" until the length of key is the same of the text length.

Key : LEMONLEMONLE

Then, compare the text and key using vigenere table.

Plaintext: ATTACKATDAWN
Key:         LEMONLEMONLE

Key is the row and plaintext is the column. for example, ROW L and COLUMN A is L. ROW E and COLUMN T is X and so on.

Cipher:    LXFOPVEFRNHR

Note: just ignore the null or replace with other alphabet


Let Decrypt the cipher

Cipher:    LXFOPVEFRNHR
Key:        LEMONLEMONLE

Key is the column. at L column find the letter Cipher L and the row letter is A. at E column find the letter Cipher X and the row letter is T and so on until you get

Plaintext: ATTACKATDAWN

To decrypt Vigenere cipeher without Key is difficult..This cipher was so strong because by swapping between all 26 possible Caesar ciphers it reduced the effectiveness of frequency analysis.

But during the Crimean War of the 1850s, Charles Babbage, under pressure of the British government, broke this cipher. The steps are :-
  1. Look for sequences of letters that appear more than once in the ciphertext.
  2. Then used vigenere table to find the most common spacing factor to identify the length of the keyword.
  3. Having established the length of the keyword and performed a frequency analysis of the portion of the ciphertext corresponding to that letter.
  4. Then, matched the frequency analysis data to the frequency in normal english to find that letter of the keyword.
  5. Repeated this for every letter in the keyword.

The Rail Fence Cipher and how to decrypt

The Rail Fence Cipher is a type of transposition cipher. A transposition cipher involves the rearranging of the letters in the plaintext to encrypt the message. This is in contrast to a substitution cipher, in which the plaintext letters are replaced by letters from another alphabet (or by different letters from the same alphabet).

note: The rail fence cipher is not very strong; the number of practical keys (the number of rails) is small enough that a crypt analyst can try them all by hand.

In the rail fence cipher, the plaintext is written downwards and diagonally on successive "rails" of an imaginary fence, then moving up when we reach the bottom rail. When we reach the top rail, the message is written downwards again until the whole plaintext is written out. The message is then read off in rows. For example, if we have 4 "rails" and a message of 'REPEAT ATTACK TONIGHT', the cipherer writes out:

3 rails

R . . . A . . . T . . . K . . . N . . . T
. E . E . T . A . T . C . X . O . I . H .
. . P . . . X . . . A . . . T . . . G . .

Encrypted :RATKNTEETATCXOIHPXATG

4 rails

R . . . . . X . . . . . K . . . . . G . .
. E . . . T . A . . . C . X . . . I . H .
. . P . A . . . T . A . . . T . N . . . T
. . . E . . . . . T . . . . . O . . . . .

Encrypted :RXKGETACXIHPATATNTETO

Note: Space in text are replaced with any suitable random alphabet. in this case iam using 'X' as replace of white space

Download code :- RFcipher


oopss.. i miss how to decrypt without key

2. Decrypt without key

In railfence cipher, the maximun level we can make is the length of text. If the ciphertext length is 100, so the maximum level is 100. To decrypt that ciphertext, the possibility of correct message will get is 100.  Below is example of decrypt without key..



  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/*
   authors by hafiq
   
   Rail Fence cipher and decrypt with key and no key
   
   any expert can advise me to improve this code...tq..
*/
import java.util.*;

public class RFCipher {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String line = System.getProperty("line.separator");
        scan.useDelimiter(line);

        System.out.print("1. Encrypt 2. Decrypt :");
        int option = scan.nextInt();

        switch (option) {
            case 1:
                System.out.print("Enter Plain Text: ");
                String text = scan.next();

                System.out.print("Enter Key Level [more than 1] :");
                int key = scan.nextInt();

                if (key > 1) {
                    String enc = RFEncryptionWork(key, text);
                    System.out.println("Encrypted :" + enc);
                } else
                    System.out.println("invalid level");
                break;
            case 2:
                System.out.print("Enter Cipher text: ");
                String enc = scan.next();
                
                System.out.print("1. No key 2. With Key: ");
                int k = scan.nextInt();
                if(k==1){
                   String[] dec = RFDecryptionWork(enc);
                   for (String a: dec) {
                       System.out.println(a);
                   }
                }
                else{
                  System.out.print("Enter Key Level [more than 1] :");
                  key = scan.nextInt();
                  String dec = RFDecryptionWork(enc,key);
                  System.out.println("Decrypted :"+dec);
                }
                break;
            default:
                break;
        }


    }
    static String RFEncryptionWork(int key, String text) {
        int move = 1;
        int count = 0;
        String[][] rfp = new String[key][text.length()];

        // arrange dot fence
        for (int x = 0; x < rfp.length; x++) {
            for (int y = 0; y < rfp[x].length; y++) {
                rfp[x][y] = ".";
            }
        }

        // formatting according fence rails
        for (int i = 0; i < text.length(); i++) {
            if ((move % 2) != 0) {
                rfp[count][i] = "" + text.charAt(i);
                if (count == (key - 1)) {
                    move = 2;
                    count = (key - 2);
                } else
                    count++;
            } else if ((move % 2) == 0) {
                rfp[count][i] = "" + text.charAt(i);
                if (count == 0) {
                    move = 1;
                    count = 1;
                } else
                    count--;
            }

        }

        //replace any white space with X or random
        for (int x = 0; x < rfp.length; x++) {
            for (int y = 0; y < rfp[x].length; y++) {
                if (rfp[x][y].equals(" "))
                    rfp[x][y] = "X";
            }
        }

        // display
        System.out.println();
        for (int i = 0; i < rfp.length; i++) {
            for (int u = 0; u < rfp[i].length; u++) {
                System.out.print(rfp[i][u] + " ");
            }
            System.out.println();
        }
        System.out.println();

        StringBuilder cb = new StringBuilder();
        //encode string from fence
        for (int i = 0; i < rfp.length; i++) {
            for (int u = 0; u < rfp[i].length; u++) {
                if (!".".equals(rfp[i][u])) {
                    cb.append(rfp[i][u]);
                }
            }
        }

        return "" + cb;
    }

    static String[] RFDecryptionWork(String text) {

        String[] ans = new String[text.length() - 2];
        for (int z = 2; z < text.length(); z++) {
            int key = z;
            String[][] rfp = new String[key][text.length()];

            for (int x = 0; x < rfp.length; x++) {
                for (int y = 0; y < rfp[x].length; y++) {
                    rfp[x][y] = ".";
                }
            }

            // arrange accroding to fence rail
            int count = 0;
            int c = 1;
            int a = 0, b = 0;
            int init = (2 * key) - 2;
            a = init - 2;
            b = 2;
            for (int i = 0; i < rfp.length; i++) {
                c = 0;
                for (int u = i; u < rfp[i].length;) {
                    if (count != text.length()) {
                        if (i == 0 || i == key - 1) {
                            rfp[i][u] = "" + text.charAt(count);
                            u = u + init;
                        } else {
                            rfp[i][u] = "" + text.charAt(count);
                            if (c % 2 == 0)
                                u = u + a;
                            else if (c % 2 == 1)
                                u = u + b;
                            c++;
                        }
                        count++;
                    } else
                        break;

                }
                if (i != 0 && i != key - 1) {
                    a = a - 2;
                    b = b + 2;
                }
            }

            int move = 1;
            count = 0;
            String sb = "";
            for (int i = 0; i < text.length(); i++) {
                if ((move % 2) != 0) {
                    sb = sb + rfp[count][i];
                    if (count == (key - 1)) {
                        move = 2;
                        count = (key - 2);
                    } else
                        count++;
                } else if ((move % 2) == 0) {
                    sb = sb + rfp[count][i];
                    if (count == 0) {
                        move = 1;
                        count = 1;
                    } else
                        count--;
                }

            }

            ans[z - 2] = sb;
        }
        return ans;
    }

    static String RFDecryptionWork(String text, int key) {
        String[][] rfp = new String[key][text.length()];

        for (int x = 0; x < rfp.length; x++) {
            for (int y = 0; y < rfp[x].length; y++) {
                rfp[x][y] = ".";
            }
        }

        // arrange accroding to fence rail
        int count = 0;
        int c = 1;
        int a = 0, b = 0;
        int init = (2 * key) - 2;
        a = init - 2;
        b = 2;
        for (int i = 0; i < rfp.length; i++) {
            c = 0;
            for (int u = i; u < rfp[i].length;) {
                if (count != text.length()) {
                    if (i == 0 || i == key - 1) {
                        rfp[i][u] = "" + text.charAt(count);
                        u = u + init;
                    } else {
                        rfp[i][u] = "" + text.charAt(count);
                        if (c % 2 == 0)
                            u = u + a;
                        else if (c % 2 == 1)
                            u = u + b;
                        c++;
                    }
                    count++;
                } else
                    break;

            }
            if (i != 0 && i != key - 1) {
                a = a - 2;
                b = b + 2;
            }
        }

        //display
        System.out.println("\n\nDecrypting..list into table");

        for (int i = 0; i < rfp.length; i++) {
            for (int u = 0; u < rfp[i].length; u++) {
                System.out.print(rfp[i][u] + " ");
            }
            System.out.println();
        }

        int move = 1;
        count = 0;
        String sb = "";
        for (int i = 0; i < text.length(); i++) {
            if ((move % 2) != 0) {
                sb = sb + rfp[count][i];
                if (count == (key - 1)) {
                    move = 2;
                    count = (key - 2);
                } else
                    count++;
            } else if ((move % 2) == 0) {
                sb = sb + rfp[count][i];
                if (count == 0) {
                    move = 1;
                    count = 1;
                } else
                    count--;
            }

        }
        
        return sb;
    }
}