Simplified RC4 Encryption
RC4 Encryption in Simple Terms
RC4 is a stream cipher, which means it generates a long sequence of random-looking numbers (called a keystream) and uses that sequence to hide or reveal data. In other words, its steps can be composed into two big steps. First, use algorithms to generate a keystream (end result key). Second, use the keystream to encrypt or decrypt data. In RC4 we apply XOR via keystream on a plain text data to encrypt it. So, just like XOR, it’s symmetric meaning the same process is used to encrypt and decrypt.
The pieces involved in RC4 are:
- S Array: a box with 256 slots, filled with the numbers 0–255. So, we just create an array with 256 slots (0,1,2...255). This is shuffled around using logic and algorithms described in this article.
- K Array: a key-based sequence, created from the secret key, that decides how the S Array is shuffled. This is an array of 256 slots as well (0,1,2...255), but these slots are filled with the secret key we define. So, for example if the secret key is ‘a b c’, the K array will be filled as follows: K[0] = a, K[1] = b, K[2] = c, K[3] = a, K[4] = b, K[5] = c, K[6] = a, etc..
- Key Scheduling Algorithm (KSA): the process that mixes the S Array using the key (in the K array). K array with our key is applied on the S array and changes the initial S array to produce a unique shuffled S Array. This is done via the logic of the algorithm described in this article.
- Pseudo-Random Generation Algorithm (PRGA): the process that uses the newly shuffled S Array to generate the keystream (the random-looking numbers). This is done via the logic of the algorithm described in this article.
- Keystream: the output of the PRGA. This is what gets XOR’ed with the plaintext data to produce ciphertext, or XOR’ed with the ciphertext to get back plaintext.
In simple terms, RC4 works by shuffling numbers in a box (S Array), using your secret key to guide the shuffle (K Array + KSA). Then, it pulls out numbers one by one to form the keystream (PRGA). Finally, the keystream is combined with your message using XOR to encrypt or decrypt.
This way, the same key that encrypted the message can also decrypt it, making RC4 a fast and symmetric encryption method.
Algorithms
We use 2 algorithms in RC4 Encryption:
- Key Scheduling
- Pseudo - Random Generation Algorithm (Stream Generation)
Key Scheduling
This algorithm eventually fills the S
array with random looking bytes that were produced using the K
array that is filled with our ASCII Encoded Key. This random looking S
array is then used by the PRGA (Pseudo-Random Generation Algorithm) to produce a Keystream. This KeyStream is in essence then our secret key to encrypt data.
Logic (pseudocode):
j = 0
for i = 0 to 255 do
j = j + S[i] + K[i] mod 256
swap S[i] and S[j]
end for
In C
:
j = 0;
for (i = 0; i < 256; i++) {
j = (j + S[i] + K[i]) % 256;
unsigned char temp = S[i];
S[i] = S[j];
S[j] = temp;
}
You have two things:
S
→ a box of 256 numbers (0–255) that gets shuffled.K
→ your secret key, repeated to fill 256 positions.
Now the loop:
- Start with
j = 0
. - Go through each
i
from 0 to 255:- Add
S[i]
andK[i]
toj
, then keep only the remainder after dividing by 256 (mod 256
).
→ this meansj
is always between 0–255. - Swap
S[i]
withS[j]
.
→ this mixesS
around depending on your key.temp
= just a helper variable to store one value while you swap.
- Add
S
has been scrambled in a key-dependent way.Pseudo - Random Generation Algorithm (Stream Generation)
The purpose of this algorithm is to take the filled S
array and create a KeyStream from it. The keystream will be used to encrypt our data.
Logic (pseudocode):
set i and j back to 0
for i = i+1
j = j + S[i] mod 256
swap S[i] and S[j]
t = S[i] + S[j] mod 256
KeyStream = S[t]
end for
In C
:
i = 0;
j = 0;
for (i = 1; i < 256; i++) {
j = (j + S[i]) % 256;
unsigned char temp = S[i];
S[i] = S[j];
S[j] = temp;
t = (S[i] + S[j]) % 256;
keyStream = S[t];
}
Encryption & Decryption in RC4
We then use xor encryption using our keystream to encrypt and decrypt data
- Cipher Text (CT)
- Plain Text (PT)
Logic (pseudocode):
CT = PT xor KeyStream
PT = CT xor KeyStream
Simplified RC4 Length 8
Define our Arrays and Key
- Suppose the S-Array of length 8 whereby:
- S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7] = 0,1,2,3,4,5,6,7
- Let the key be K = 31415
- The K array thus is:
- K[0], K[1], K[2], K[3], K[4], K[5], K[6], K[7] = 3,1,4,1,5,3,1,4
Key Scheduling Begins
In C
:
j = 0;
for (i = 0; i < 8; i++) {
j = (j + S[i] + K[i]) % 8;
unsigned char temp = S[i];
S[i] = S[j];
S[j] = temp;
}
Now let's walk through the code:
- We start with
j = 0
andi = 0
- Hence a new
j
wheni = 0
is: j = j + S[i] + K[i] mod 8
j = 0 + 0 + 3 mod 8 = 3
(seej = 3
in purple in the table neari = 0
)K[0], K[1], K[2], K[3], K[4], K[5], K[6], K[7]
=--[ 3, 1, 4, 1, 5, 3, 1, 4 ]--
- Now we need to swap
S[i]
andS[j]
- →
S[i]
is 0 becausei
is 0 now in this iteration. And the element of theS
array in the position 0 is 0 (see the yellow value in the table in row 1). - →
S[j]
is 3, becausej
is 3 as we just calculated. So, the current element of theS
array in the position 3 is 3. - Hence, we need to swap 0 with 3 in the
S
array (see blue cells in row 2). - Values that do not require swapping in the rest of the positions of the
S
array remain the same. - Hence our new
S
array is--[ 3 1 2 0 4 5 6 7 ]--
.
- →
In C
:
was --> 0 1 2 3 4 5 6 7
swap 0 and 3
now --> 3 1 2 0 4 5 6 7
Repeat the Steps until you arrive at the final S array (in green) `3 5 0 1 7 6 4 2`

Simplified Stream Generation (Pseudo-Random)
Define What we Want to Encrypt
- So we have our new S array:
--[ 3 5 0 1 7 6 4 2 ]--
- Let’s say we have our plain text array
--[ 6 1 5 4 ]--
(we assume that this is encoded plain text that we want to encrypt). - The length of the Plain Text array is 4 (
0 1 2 3
).
Proceed with Pseudo - Random Generation Algorithm (Stream Generation)
Crucial here is that we will perform this until we reach the length of the plain text (to length of PT):
set i and j back to 0
for i = i+1 to length of PT
j = j + S[i] mod 8
swap S[i] and S[j]
t = S[i] + S [j] mod 8
KeyStream = S[t]
end for
Let’s walk through the first iteration:
- Our
i
andj
are 0. - First iteration is
i + 1
, hence ouri
is 1. - Let’s calculate our first
j
wheni
is 1.
→ our firstj
is 5 (see second row in purple).
j = j + S[i] mod 8
j = 0 + 5 mod 8 = 5
- Now swap
S[i]
which isS[1]
(since i is 1, which is 5) withS[j]
which isS[5]
(since j is 5, which is 6).- See what we swapped in row 2 highlighted in turquoise.
- Now our new S array is
--[ 3 6 0 1 7 5 4 2 ]--
→ see row 2 (S --->
) - Now we calculate the
t
:
t = S[i] + S[j] mod 8
t = 6 + 5 mod 8 = 11 mod 8 = 3
(see t in row 2 in red)
→ pay attention that in this case S[i]
is 6
and not 5
because we swapped in the previous step.
- Now calculate the
Kstr
or the KeyStream:
KeyStream = S[t]
KeyStream = S[3]
KeyStream = 1

Our KeyStream is --[ 1 0 0 2 ]--
Simplified Encryption
- We have our Keystream (KS):
1 0 0 2
- We have our Plain Text (PT):
6 1 5 4
- Let's Create our Cipher Text (CT)
- CT = PT xor KS
- First Change the Plain Text and the KeyStream to binary
PT: 0110 0001 0101 0100
KS: 0001 0000 0000 0010
- Now apply
xor
on to encrypt the PT
PT: 0110 0001 0101 0100
KS: 0001 0000 0000 0010
CT: 0111 0001 0101 0110
- Finally convert the binary CT to a numerical CT
CT Binary: 0111 0001 0101 0110
CT Numerical: 7 1 5 6
- We encrypted
6154
to7156
A Complete Simple RC4 Encryption Program in C
#include <stdio.h>
int main() {
unsigned char K[] = { 3, 1, 4, 1, 5, 3, 1, 4 };
unsigned char S[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
int j = 0;
int i = 0;
unsigned char plain_text[] = "6154";
printf("1. Plain Text to Encrypt: %s\n\n", plain_text);
printf("2. The key is: 31415\n\n");
printf("3. The S array is: ");
for (int i = 0; i < 8; i++) {
printf("%d ", S[i]);
}
printf("\n");
printf("\n");
printf("4. The K array is: ");
for (int i = 0; i < 8; i++) {
printf("%d ", K[i]);
}
printf("\n");
printf("\n");
for (i = 0; i < 8; i++) {
j = (j + S[i] + K[i]) % 8;
unsigned char temp = S[i];
S[i] = S[j];
S[j] = temp;
}
printf("5. New S array is: ");
for (i = 0; i < 8; i++) {
printf("%d ", S[i]);
}
printf("\n");
printf("\n");
j = 0;
i = 0;
unsigned char KeyStream[4];
int t;
for (i = 1; i < 5; i++) {
j = (j + S[i]) % 8;
unsigned char temp = S[i];
S[i] = S[j];
S[j] = temp;
t = (S[i] + S[j]) % 8;
KeyStream[i - 1] = S[t];
}
printf("6. New KeyStream array is: ");
for (i = 0; i < 4; i++) {
printf("%d ", KeyStream[i]);
}
printf("\n");
printf("\n");
unsigned char shifr[4];
for (i = 0; i < 4; i++) {
shifr[i] = plain_text[i] ^ KeyStream[i];
}
printf("7. Encrypted Result (hex): ");
for (i = 0; i < 4; i++) {
printf("\\x%02x", shifr[i]);
}
printf("\n");
printf("\n");
printf("8. Encrypted Result (text): ");
for (i = 0; i < 4; i++) {
printf("%c", shifr[i]);
}
printf("\n");
printf("\n");
printf("9. Decrypted Result (text): ");
for (i = 0; i < sizeof(shifr); i++) {
printf("%c", shifr[i] ^ KeyStream[i]);
}
printf("\n");
return 0;
}