Last active
June 7, 2021 23:44
-
-
Save bneils/97c0bfae93bfe49f000b82189975df0b to your computer and use it in GitHub Desktop.
Deciphering based on lexical distributions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
// THIS ASSUMES ASCII-- not portable to EBCDIC systems | |
static int shiftletter(int c, int r); | |
int main(int argc, char *argv[]) | |
{ | |
if (argc <= 1) return 1; | |
int shift = atoi(argv[1]); | |
int c; | |
while ((c = getchar()) != EOF) | |
putchar(shiftletter(c, shift)); | |
} | |
/* shiftletter: shift char right one in the alphabet */ | |
static int shiftletter(int c, int r) | |
{ | |
if ('a' <= c && c <= 'z') return (c - 'a' + r) % ('z' - 'a' + 1) + 'a'; | |
if ('A' <= c && c <= 'Z') return (c - 'A' + r) % ('Z' - 'A' + 1) + 'A'; | |
return c; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <ctype.h> | |
#include <string.h> | |
#include <float.h> | |
#define BUFSIZE 10000 | |
#define NLETTER 26 | |
// THIS ASSUMES ASCII-- not portable to EBCDIC systems | |
char s[BUFSIZE]; | |
/* contains freq of letters A-Z in the english language */ | |
/* analyzed lexical frequencies in words_alpha.txt */ | |
float normFreq[] = { | |
0.084643, | |
0.018296, | |
0.043775, | |
0.032389, | |
0.107721, | |
0.011228, | |
0.023643, | |
0.026432, | |
0.089566, | |
0.001561, | |
0.007673, | |
0.055774, | |
0.030105, | |
0.071948, | |
0.071993, | |
0.032524, | |
0.001683, | |
0.070433, | |
0.071618, | |
0.066070, | |
0.037627, | |
0.009464, | |
0.006412, | |
0.003003, | |
0.020196, | |
0.004223, | |
}; | |
static int shiftletter(int c, int r); | |
static int alphapos(int c); | |
int main(void) | |
{ | |
char *x = s; | |
int c, n, len; | |
int bestShift = 0; | |
float minDev = FLT_MAX; | |
while ((c = getchar()) != EOF) /* copy */ | |
{ | |
*x++ = c; | |
if (isalpha(c)) ++n; | |
} | |
len = x - s; | |
for (int i = 0; i < NLETTER; ++i) | |
{ | |
int freq[NLETTER] = {0}; | |
for (int j = 0; j < len; ++j) /* shift text right 1 */ | |
{ | |
if (isalpha(s[j])) | |
{ | |
freq[alphapos(s[j])]++; | |
s[j] = shiftletter(s[j], 1); | |
} | |
} | |
float stdDevSqr = 0; | |
for (int j = 0; j < NLETTER; ++j) /* get percentage & calc square of std dev */ | |
{ | |
float x = (float)freq[j] / n - normFreq[j]; | |
stdDevSqr += x * x; | |
} | |
if (stdDevSqr < minDev) /* get min */ | |
{ | |
minDev = stdDevSqr; | |
bestShift = i; | |
} | |
} | |
for (int i = 0; i < len; ++i) /* get shifted result */ | |
putchar(shiftletter(s[i], bestShift)); | |
putchar('\n'); | |
} | |
/* shiftletter: shift char right one in the alphabet */ | |
static int shiftletter(int c, int r) | |
{ | |
if ('a' <= c && c <= 'z') return (c - 'a' + r) % ('z' - 'a' + 1) + 'a'; | |
if ('A' <= c && c <= 'Z') return (c - 'A' + r) % ('Z' - 'A' + 1) + 'A'; | |
return c; | |
} | |
/* alphapos: returns position of character in the alphabet, -1 otherwise */ | |
static int alphapos(int c) | |
{ | |
if ('a' <= c && c <= 'z') return c - 'a'; | |
if ('A' <= c && c <= 'Z') return c - 'A'; | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment