Algorithms_in_C 1.0.0
Set of algorithms implemented in C.
Loading...
Searching...
No Matches
affine.c File Reference

An affine cipher is a letter substitution cipher that uses a linear transformation to substitute letters in a message. More...

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Include dependency graph for affine.c:

Data Structures

struct  affine_key_t
 a structure representing an affine cipher key More...
 

Macros

#define ALPHABET_SIZE   95
 for assertions
 
#define Z95_CONVERSION_CONSTANT   32
 used to convert a printable byte (32 to 126) to an element of the group Z_95 (0 to 94)
 

Functions

int modular_multiplicative_inverse (unsigned int a, unsigned int m)
 finds the value x such that (a * x) % m = 1
 
affine_key_t inverse_key (affine_key_t key)
 Given a valid affine cipher key, this function will produce the inverse key.
 
void affine_encrypt (char *s, affine_key_t key)
 Encrypts character string s with key.
 
void affine_decrypt (char *s, affine_key_t key)
 Decrypts an affine ciphertext.
 
void test_string (const char *s, const char *ciphertext, int a, int b)
 Tests a given string.
 
static void tests ()
 Test multiple strings.
 
int main ()
 main function
 

Detailed Description

An affine cipher is a letter substitution cipher that uses a linear transformation to substitute letters in a message.

Given an alphabet of length M with characters with numeric values 0-(M-1), an arbitrary character x can be transformed with the expression (ax

  • b) % M into our ciphertext character. The only caveat is that a must be relatively prime with M in order for this transformation to be invertible, i.e., gcd(a, M) = 1.
    Author
    Daniel Murrow

Macro Definition Documentation

◆ ALPHABET_SIZE

#define ALPHABET_SIZE   95

for assertions

for IO for div function and div_t struct as well as malloc and free for strlen, strcpy, and strcmp

number of characters in our alphabet (printable ASCII characters)

Function Documentation

◆ affine_decrypt()

void affine_decrypt ( char *  s,
affine_key_t  key 
)

Decrypts an affine ciphertext.

Parameters
sstring to be decrypted
keyKey used when s was encrypted
Returns
void
133{
134 affine_key_t inverse = inverse_key(key);
135
136 for (int i = 0; s[i] != '\0'; i++)
137 {
138 int c = (int)s[i] - Z95_CONVERSION_CONSTANT;
139
140 c += inverse.b;
141 c *= inverse.a;
142 c %= ALPHABET_SIZE;
143
144 s[i] = (char)(c + Z95_CONVERSION_CONSTANT);
145 }
146}
#define ALPHABET_SIZE
for assertions
Definition affine.c:22
#define Z95_CONVERSION_CONSTANT
used to convert a printable byte (32 to 126) to an element of the group Z_95 (0 to 94)
Definition affine.c:28
affine_key_t inverse_key(affine_key_t key)
Given a valid affine cipher key, this function will produce the inverse key.
Definition affine.c:87
a structure representing an affine cipher key
Definition affine.c:34
int a
what the character is being multiplied by
Definition affine.c:35
int b
what is being added after the multiplication with a
Definition affine.c:36
Here is the call graph for this function:

◆ affine_encrypt()

void affine_encrypt ( char *  s,
affine_key_t  key 
)

Encrypts character string s with key.

Parameters
sstring to be encrypted
keyaffine key used for encryption
Returns
void
111{
112 for (int i = 0; s[i] != '\0'; i++)
113 {
114 int c = (int)s[i] - Z95_CONVERSION_CONSTANT;
115
116 c *= key.a;
117 c += key.b;
118 c %= ALPHABET_SIZE;
119
120 s[i] = (char)(c + Z95_CONVERSION_CONSTANT);
121 }
122}

◆ inverse_key()

affine_key_t inverse_key ( affine_key_t  key)

Given a valid affine cipher key, this function will produce the inverse key.

Parameters
keyThey key to be inverted
Returns
inverse of key
88{
89 affine_key_t inverse;
90
92
93 // Turn negative results positive
94 inverse.a += ALPHABET_SIZE;
95 inverse.a %= ALPHABET_SIZE;
96
97 inverse.b = -(key.b % ALPHABET_SIZE) + ALPHABET_SIZE;
98
99 return inverse;
100}
int modular_multiplicative_inverse(unsigned int a, unsigned int m)
finds the value x such that (a * x) % m = 1
Definition affine.c:47
Here is the call graph for this function:

◆ main()

int main ( void  )

main function

Returns
0 upon successful program exit
204{
205 tests();
206 return 0;
207}
static void tests()
Test multiple strings.
Definition affine.c:179
Here is the call graph for this function:

◆ modular_multiplicative_inverse()

int modular_multiplicative_inverse ( unsigned int  a,
unsigned int  m 
)

finds the value x such that (a * x) % m = 1

Parameters
anumber we are finding the inverse for
mthe modulus the inversion is based on
Returns
the modular multiplicative inverse of a mod m
48{
49 int x[2] = {1, 0};
50 div_t div_result;
51
52 if (m == 0) {
53 return 0;
54 }
55 a %= m;
56 if (a == 0) {
57 return 0;
58 }
59
60 div_result.rem = a;
61
62 while (div_result.rem > 0)
63 {
64 div_result = div(m, a);
65
66 m = a;
67 a = div_result.rem;
68
69 // Calculate value of x for this iteration
70 int next = x[1] - (x[0] * div_result.quot);
71
72 x[1] = x[0];
73 x[0] = next;
74 }
75
76 return x[1];
77}
int next(Vector *vec)
This function gets the next item from the Vector each time it's called.
Definition vector.c:102
Here is the call graph for this function:

◆ test_string()

void test_string ( const char *  s,
const char *  ciphertext,
int  a,
int  b 
)

Tests a given string.

Parameters
sstring to be tested
avalue of key.a
bvalue of key.b
Returns
void
158{
159 char *copy = malloc((strlen(s) + 1) * sizeof(char));
160 strcpy(copy, s);
161
162 affine_key_t key = {a, b};
163
164 affine_encrypt(copy, key);
165 assert(strcmp(copy, ciphertext) == 0); // assert that the encryption worked
166
167 affine_decrypt(copy, key);
168 assert(strcmp(copy, s) ==
169 0); // assert that we got the same string we started with
170
171 free(copy);
172}
void affine_encrypt(char *s, affine_key_t key)
Encrypts character string s with key.
Definition affine.c:110
void affine_decrypt(char *s, affine_key_t key)
Decrypts an affine ciphertext.
Definition affine.c:132
#define malloc(bytes)
This macro replace the standard malloc function with malloc_dbg.
Definition malloc_dbg.h:18
#define free(ptr)
This macro replace the standard free function with free_dbg.
Definition malloc_dbg.h:26
Here is the call graph for this function:

◆ tests()

static void tests ( )
static

Test multiple strings.

Returns
void
180{
181 test_string("Hello!", "&3ddy2", 7, 11);
182 test_string("TheAlgorithms/C", "DNC}=jHS2zN!7;E", 67, 67);
183 test_string("0123456789", "840,($ {ws", 91, 88);
184 test_string("7W@;cdeRT9uL", "JDfa*we?z&bL", 77, 76);
185 test_string("~Qr%^-+++$leM", "r'qC0$sss;Ahf", 8, 90);
186 test_string("The quick brown fox jumps over the lazy dog",
187 "K7: .*6<4 =-0(1 90' 5*2/, 0):- +7: 3>%& ;08", 94, 0);
189 "One-1, Two-2, Three-3, Four-4, Five-5, Six-6, Seven-7, Eight-8, "
190 "Nine-9, Ten-10",
191 "H&60>\\2*uY0q\\2*p4660E\\2XYn40x\\2XDB60L\\2VDI0 "
192 "\\2V6B6&0S\\2%D=p;0'\\2tD&60Z\\2*6&0>j",
193 51, 18);
194
195 printf("All tests have successfully passed!\n");
196}
void test_string(const char *s, const char *ciphertext, int a, int b)
Tests a given string.
Definition affine.c:157
Here is the call graph for this function: