- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试实现一种替换密码,将字母表向前移动三个字母来加密文本。
如何通过比较实际字母频率与平均字母频率来解密文本。
下面的代码生成一个数组,其中包含加密文本中的实际字母频率。
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static char clef[][7] =
{
['A'] = "X",
['B'] = "Y",
['C'] = "Z",
['D'] = "A",
['E'] = "B",
['F'] = "C",
['G'] = "D",
['H'] = "E",
['I'] = "F",
['J'] = "G",
['K'] = "H",
['L'] = "I",
['M'] = "J",
['N'] = "K",
['O'] = "L",
['P'] = "M",
['Q'] = "N",
['R'] = "O",
['S'] = "P",
['T'] = "Q",
['U'] = "R",
['V'] = "S",
['W'] = "T",
['X'] = "U",
['Y'] = "V",
['Z'] = "W"
};
double frequencyEn[] = {
.082, .015, .028, .043, .127, .022,
.020, .061, .070, .002, .008, .040,
.024, .067, .075, .019, .001, .060,
.063, .091, .028, .010, .024, .002,
.020, .001 };
enum { MAX_CLEF = sizeof(clef) / sizeof(clef[0]) };
static char *prompt(FILE *fp, const char *prompt, char *buffer, size_t buflen)
{
printf("%s", prompt);
fflush(0);
return fgets(buffer, buflen, fp);
}
static void substitute(FILE *fp, const char *buffer, const char *pad1, const char *pad2)
{
int c;
const char *pad = pad1;
int col = 0;
for (int i = 0; (c = buffer[i]) != '\0'; i++)
{
if (col == 0)
{
fputs(pad, fp);
col += strlen(pad);
pad = pad2;
}
col++;
c = toupper(c);
if (c < MAX_CLEF && clef[c][0] != '\0')
{
fputs(clef[c], fp);
col += strlen(clef[c]);
}
else
{
putc(c, fp);
col++;
}
if (col > 72)
{
putc('\n', fp);
col = 0;
}
}
}
int main(void)
{
char * buffer = 0;
char * cryptText = 0;
long length;
FILE * plainTextFile = fopen ("plaintext.txt", "rb");
FILE * cipherTextFile = fopen("ciphertext.txt", "w+");
char string[100];
int c = 0, count[26] = {0};
int accum = 0;
if (plainTextFile)
{
fseek (plainTextFile, 0, SEEK_END);
length = ftell (plainTextFile);
fseek (plainTextFile, 0, SEEK_SET);
buffer = malloc (length);
if (buffer)
{
fread (buffer, 1, length, plainTextFile);
}
fclose (plainTextFile);
}
if (buffer)
{
printf("%s", buffer);
}
else {
printf("failure");
}
substitute(cipherTextFile, buffer, "", " ");
if (cipherTextFile)
{
fseek (cipherTextFile, 0, SEEK_END);
length = ftell (cipherTextFile);
fseek (cipherTextFile, 0, SEEK_SET);
cryptText = malloc (length);
if (cryptText)
{
fread (cryptText, 1, length, cipherTextFile);
}
fclose (cipherTextFile);
}
if (cryptText)
{
printf("%s", cryptText);
}
else {
printf("failure");
}
while ( cryptText[c] != '\0' )
{
if ( cryptText[c] >= 'a' && cryptText[c] <= 'z' ){
count[cryptText[c]-'a']++;
accum++;
}
else if (cryptText[c] >= 'A' && cryptText[c] <= 'Z'){
count[cryptText[c]-'A']++;
accum++;
}
c++;
}
for ( c = 0 ; c < 26 ; c++ )
{
if( count[c] != 0 )
printf( "%c %f\n", c+'a', ((double)count[c])/accum);
}
}
最佳答案
Chi-Squared Test计算预期值 Ei 与观测值 Oi 之间差值的平方和em>,除以期望值。维基百科页面甚至提到了一个应用程序:
In cryptanalysis, chi-square test is used to compare the distribution of plaintext and (possibly) decrypted ciphertext. The lowest value of the test means that the decryption was successful with high probability.
将其应用于当前的问题,您提供了普通英语文本中不同字母的预期频率的表格。我们需要一个程序将凯撒密码应用于给定的明文(或密文):
ec97.c
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
// #include "stderr.h"
void err_setarg0(const char *argv0);
void err_usage(const char *usestr);
void err_error(const char *errmsg);
int main(int argc, char **argv)
{
char *buffer = 0;
size_t buflen = 0;
err_setarg0(argv[0]);
if (argc != 2)
err_usage("offset");
int offset = atoi(argv[1]) % 26;
if (offset < 0)
err_error("Offset should be a positive number 1..25\n");
while (getline(&buffer, &buflen, stdin) != -1)
{
char *ptr = buffer;
unsigned char u;
while ((u = (unsigned char)*ptr++) != '\0')
{
if (isupper(u))
u = (u - 'A' + offset) % 26 + 'A';
else if (islower(u))
u = (u - 'a' + offset) % 26 + 'a';
putchar(u);
}
}
free(buffer);
return 0;
}
// Minimal stderr.c code
static const char *arg0 = "unknown";
void err_setarg0(const char *argv0)
{
arg0 = argv0;
}
void err_usage(const char *usestr)
{
fprintf(stderr, "Usage: %s %s\n", arg0, usestr);
exit(EXIT_FAILURE);
}
void err_error(const char *errmsg)
{
fprintf(stderr, "%s: %s\n", arg0, errmsg);
exit(EXIT_FAILURE);
}
使用示例(程序ec97
):
$ ec97 3 <<< 'The quick brown fox jumped over the lazy dog!'
Wkh txlfn eurzq ira mxpshg ryhu wkh odcb grj!
$ ec97 23 <<< 'Wkh txlfn eurzq ira mxpshg ryhu wkh odcb grj!'
The quick brown fox jumped over the lazy dog!
$
我们需要一个程序:
或者,在代码中:
dc97.c
/* Determine shift used for text encrypted using Caesar Cipher */
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
/* Letter frequencies a-z in English */
static const float freq_en[] =
{
.082, .015, .028, .043, .127, .022,
.020, .061, .070, .002, .008, .040,
.024, .067, .075, .019, .001, .060,
.063, .091, .028, .010, .024, .002,
.020, .001
};
int main(void)
{
char *buffer = 0;
size_t buflen = 0;
size_t freq[26] = { 0 };
size_t count = 0;
while (getline(&buffer, &buflen, stdin) != -1)
{
char *ptr = buffer;
unsigned char u;
while ((u = (unsigned char)*ptr++) != '\0')
{
if (isalpha(u))
{
count++;
freq[tolower(u) - 'a']++;
}
}
}
free(buffer);
if (count == 0)
{
fprintf(stderr, "No data read!\n");
return 1;
}
double chisq[26];
for (int shift = 0; shift < 26; shift++)
{
chisq[shift] = 0.0;
for (int letter = 0; letter < 26; letter++)
{
int index = (shift + letter) % 26;
double delta = freq[index] - count * freq_en[letter];
chisq[shift] += (delta * delta) / (count * freq_en[letter]);
}
printf("'%c' = %13.6f\n", shift + 'A', chisq[shift]);
}
int min_i = 0;
double val_i = chisq[0];
for (int i = 1; i < 26; i++)
{
if (chisq[i] < val_i)
{
val_i = chisq[i];
min_i = i;
}
}
printf("Best match is (%d) '%c' = %10.6f\n", min_i, min_i + 'A', val_i);
return 0;
}
运行示例:
$ ec97 3 <<< 'The quick brown fox jumped over the lazy dog!' | dc97
'A' = 143.784398
'B' = 564.772479
'C' = 125.131609
'D' = 87.069134
'E' = 178.249272
'F' = 90.994048
'G' = 194.326935
'H' = 301.117365
'I' = 710.786241
'J' = 147.377473
'K' = 304.179348
'L' = 243.699823
'M' = 137.639230
'N' = 183.885553
'O' = 135.720804
'P' = 106.261239
'Q' = 196.046792
'R' = 506.812184
'S' = 517.893291
'T' = 106.267925
'U' = 375.525078
'V' = 202.806561
'W' = 116.660543
'X' = 304.590809
'Y' = 364.746822
'Z' = 139.113568
Best match is (3) 'D' = 87.069134
$
我还在程序源代码上运行了它,以及目录中的makefile,并且几个数据文件。第一个是废话,通常称为'The Great Panjandrum' :
So she went into the garden
to cut a cabbage-leaf
to make an apple-pie
and at the same time
a great she-bear coming down the street
pops its head into the shop
What no soap
So he died
and she very imprudently married the Barber
and there were present
the Picninnies
and the Joblillies
and the Garyulies
and the great Panjandrum himself
with the little round button at top
and they all fell to playing the game of catch-as-catch-can
till the gunpowder ran out at the heels of their boots
第二个是针对这个问题精心设计的:
Bond was on a roll, playing jazz on his sax.
In all of his doings, nothing was as bad as what was going on now,
but nary a jocular hint did his writing contain that
all was not going as his boss though it would.
Quit? Zounds! No way to quit now.
其中没有 e,人们可能会认为这可能会导致问题,但看起来没有问题。
$ x=$(random 1 25)
$ ec97 $x < great.panjandrum
Uq ujg ygpv kpvq vjg ictfgp
vq ewv c ecddcig-ngch
vq ocmg cp crrng-rkg
cpf cv vjg ucog vkog
c itgcv ujg-dgct eqokpi fqyp vjg uvtggv
rqru kvu jgcf kpvq vjg ujqr
Yjcv pq uqcr
Uq jg fkgf
cpf ujg xgta kortwfgpvna octtkgf vjg Dctdgt
cpf vjgtg ygtg rtgugpv
vjg Rkepkppkgu
cpf vjg Lqdnknnkgu
cpf vjg Ictawnkgu
cpf vjg itgcv Rcplcpftwo jkougnh
ykvj vjg nkvvng tqwpf dwvvqp cv vqr
cpf vjga cnn hgnn vq rncakpi vjg icog qh ecvej-cu-ecvej-ecp
vknn vjg iwprqyfgt tcp qwv cv vjg jggnu qh vjgkt dqqvu
$ ec97 $x | dc97
'A' = 3403.710518
'B' = 1821.123417
'C' = 29.719952
'D' = 5238.969620
'E' = 2077.413735
'F' = 8274.966485
'G' = 2446.331525
'H' = 8950.309208
'I' = 1362.257963
'J' = 4419.368172
'K' = 3161.502276
'L' = 3113.030682
'M' = 7778.647756
'N' = 1112.302912
'O' = 1497.782346
'P' = 1490.896824
'Q' = 10395.032795
'R' = 1985.696886
'S' = 2382.319358
'T' = 4874.708427
'U' = 3280.570608
'V' = 1467.488275
'W' = 7318.221432
'X' = 5634.124795
'Y' = 3108.392584
'Z' = 2849.154134
Best match is (2) 'C' = 29.719952
$ echo "Key = $x"
Key = 2
$
$ x=$(random 1 25)
$ ec97 $x < bond.jazz
Ylka txp lk x olii, mixvfkd gxww lk efp pxu.
Fk xii lc efp alfkdp, klqefkd txp xp yxa xp texq txp dlfkd lk klt,
yrq kxov x glzrixo efkq afa efp tofqfkd zlkqxfk qexq
xii txp klq dlfkd xp efp ylpp qelrde fq tlria.
Nrfq? Wlrkap! Kl txv ql nrfq klt.
$ ec97 $x < bond.jazz | dc97
'A' = 2630.974532
'B' = 2107.704681
'C' = 1473.828862
'D' = 865.368278
'E' = 715.940980
'F' = 1010.885486
'G' = 2881.481606
'H' = 3297.014998
'I' = 1302.909485
'J' = 871.665974
'K' = 917.232399
'L' = 2716.342024
'M' = 2525.973294
'N' = 2077.065275
'O' = 3096.667665
'P' = 2211.782909
'Q' = 1793.302623
'R' = 1427.340376
'S' = 1537.934006
'T' = 702.667000
'U' = 3489.590647
'V' = 3111.999371
'W' = 1445.825861
'X' = 142.412135
'Y' = 2671.998367
'Z' = 1977.131986
Best match is (23) 'X' = 142.412135
$ echo "Key = $x"
Key = 23
$
看起来效果不错。
关于c - 确定 C 中简单替换密码的移位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39458053/
我想将这个无符号数:1479636484000 向右移动 7 位。这在 JavaScript 中可能吗? 两者 1479636484000 >> 7 和 1479636484000 >>> 7 返回错
鉴于以下代码: import matplotlib.pyplot as plt import numpy as np x = [1.0, 1.1, 2.0, 5.7] y = np.arange(le
我有一个低级键盘钩子(Hook),目前允许我从任何应用程序(包括游戏)中控制媒体播放器。 它通过查看捕获的特定击键来工作。 我想扩展它以查找键的组合。我可以对一些逻辑进行硬编码,但我觉得必须有一种更合
我需要一些帮助来理解这段C代码。我不知道这里的“L”和“\”是什么?请也说明一点:) #define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>2
我正在查看一段代码: int result = 0 ; char byte = foo[j] for (i = 7 ; i>0 ; i--) { byte = (byte & ~0x1)>>1
我们有一个项目要求我们编写一个程序,允许用户输入一系列数字“将数字读入数组以进行进一步处理,用户通过输入负数表示他们已完成(负数不用于计算),在读取所有数字后执行以下操作,总结输入的#,计算输入的#,
锁定。有disputes about this question’s content正在解决中。它目前不接受新的答案或互动。 def menu(): choice = input("Pres
为什么如果 int x = -1 // binary: 11111111111111111111111111111111 x = x >>> 31; 我们有 000000000000000000000
我的问题其实应该很简单:我有一个玩家对象数组。(玩家[])我想要一个函数来旋转这个数组直到一个索引: public void rotateArray(Object[] array, int index
我有一个编码为 boost 动态位集的数字列表。我根据此列表中的任何数字可以采用的最大值动态选择此位集的大小。所以假设我有从 0 到 7 的数字,我只需要三位,我的字符串 0,2,7 将被编码为000
我能想到一些令人讨厌的低效方法来完成这项任务,但我想知道最好的方法是什么。 例如,我想复制一个字节中从第 3 位开始的 10 个字节,并像往常一样复制到一个指针。 有没有比一次复制一个移位字节更好的方
我正在尝试为该问题添加更多规则,并且该规则一直给我带来这种转变/减少冲突的能力,我不知道为什么会这样做,并且在过去的24小时内我一直在尝试解决问题 FuncDecl : RetTyp
This question already has answers here: Why does it make a difference if left and right shift are us
我在 Perl 中遇到这个问题已经有几天了,在搜索了无数的手册页、perldocs 和谷歌搜索了太多的搜索词之后,希望这里有人能帮助我。 我得到两个表示十六进制值的字符串,即“FFFF”,而不是 Pe
我有一个主 div,两个 div 水平并排放置在这个父 div 中。 .parent{ height: 360px; margin-top: 0px; bo
我想 float 我的元素列表并从第二个元素创建一个移动效果。 如何避免第二个 .item 之后的“清除”行为? .shift { float: right; width: 50%;
我正在使用 SSE3 优化我的代码。代码中有一点迫使我将 vector 中的所有元素移动一个元素 v[0] = 0 //v is some char* and N = v.size() for(i
.file "calcnew.c" .text .globl calcnew .type calcnew, @function calcnew:
我有一个点对象: class Point { final int x,y; ... } 因为这些点将在我的代码中到处使用/创建,所以我想开始使用 guavas 缓存。不幸的是
x = "Foo 890 bar *()" 如何将包括 "*()" 在内的小写字母“未移位”返回到 890?期望的结果: foo 890 bar 890 不需要的: x.lower() => "foo
我是一名优秀的程序员,十分优秀!