-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Burrows_Wheeler_Transform.c
130 lines (100 loc) · 3.26 KB
/
Burrows_Wheeler_Transform.c
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
/*Below is an implementation of Burrows Wheeler Transform in C. It restructures
the given plaintext to forms the ciphertext. It first forms all possible cyclic
rotations of the plaintext, and then sorts the rotations lexicographically. Then,
ciphertext is formed by taking the last character of each rotation sorted in
lexicographical order. This code is implemented keeping in mind that characters
in the plaintext are all unique.*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Define maximum length of plaintext, ciphertext
#define MAXLENGTH 100
// Define size of plaintext
#define size 6
// This function generates all cyclic rotations of given plaintext
void generate(char* plaintext, char combinations[][size]) {
int index = 0;
for(int i = 0; i < size; i++) {
for(int j = 0; j < size; j++) {
// Mod is used to wrap around the index
combinations[i][j] = plaintext[(index + j) % size];
}
index += 1;
}
}
// This function sorts the above rotations lexicographically.
void sort(char* plaintext, char combinations[][size], int arr[size]) {
// Calling the generate function to generate all rotations
generate(&plaintext[0], combinations);
int count = 0;
int k = 0;
while(k < size) {
// Iterate through the first column
for(int i = 0; i < 1; i++) {
/* Char { is lexicograqphically greater than
[A-Z] and [a-z]. So, we use it here as a maximum.*/
char min = '{';
int index;
// Iterate though first element of each row
for(int j = 0; j < size; j++) {
if(combinations[j][i] < min) {
// Find the minimum
min = combinations[j][i];
// Store its index
index = j;
}
}
// Add the index to the array
arr[count++] = index;
// Replace the minimum with {
combinations[index][i] = '{';
}
k++;
}
}
// This is the encrpytion function
char* encrypt(char* plaintext, char combinations[][size]) {
int arr[size];
// Calling the sort function to get the sorted order
sort(plaintext, combinations, arr);
// Declaring variable to store the ciphertext
static char encrypted[MAXLENGTH];
int count = 0;
// Adding last element of sorted rotation to the encrypted text
for(int i = 0; i < size; i++) {
encrypted[count++] = combinations[arr[i]][size - 1];
}
// Returning the encrypted message
return encrypted;
}
int main() {
printf("----------Burrows Wheeler Transform----------\n");
printf("\nCurrent size of macro n is %d\n", size);
// Taking plaintext as input from the user
char plaintext[MAXLENGTH];
printf("\nEnter plaintext of size %d: ", size);
fgets(plaintext, MAXLENGTH, stdin);
// Check if size of plaintext is equal to macro size
if(strlen(plaintext) - 1 != size) {
printf("Invalid message entered.\n");
exit(0);
}
// Decalring matrix to store the rotations
char combinations[size][size];
// Calling the encrypted fuction and printing ciphertext
char* encrypted = encrypt(&plaintext[0], combinations);
printf("The encrypted plaintext is: %s\n", encrypted);
return 0;
}
/* Sample I/O:
a)
----------Burrows Wheeler Transform----------
Current size of macro n is 10
Enter plaintext of size 10: plainwords
The encrypted plaintext is: lrapiwsodn
b)
----------Burrows Wheeler Transform----------
Current size of macro n is 6
Enter plaintext of size 6: iworld
The encrypted plaintext is: ldrwoi
*/