Skip to content

Instantly share code, notes, and snippets.

@bneils
Last active June 7, 2021 23:44
Show Gist options
  • Save bneils/97c0bfae93bfe49f000b82189975df0b to your computer and use it in GitHub Desktop.
Save bneils/97c0bfae93bfe49f000b82189975df0b to your computer and use it in GitHub Desktop.
Deciphering based on lexical distributions
#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;
}
#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