欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

****实验Lab0

程序员文章站 2022-04-26 09:39:15
...

赞赏码 & 联系方式 & 个人闲话

****前言

Lab0

1. cipher text

bmjs dtz uqfd ymj lfrj tk ymwtsjx dtz bns tw dtz inj ymjwj nx st rniiqj lwtzsi

代码:

#include<stdio.h>
#include<string.h>
int main()
{
	//密文
	char cipher[] = "bmjs dtz uqfd ymj lfrj tk ymwtsjx dtz bns tw dtz inj ymjwj nx st rniiqj lwtzsi";
	char clear[100] = { 0 };
	int i;
	//尝试25种位移量
	for (i = 1; i <= 25; i++)
	{
		memset(clear,0,sizeof(clear));
		int j;
		//对密文逐字符处理
		for (j = 0; j < strlen(cipher); j++)
		{
			int temp = int(cipher[j]);
			//若是小写字母则进行移位,其他字符不处理
			if (cipher[j] <= 'z'&&cipher[j] >= 'a')
			{
				temp = cipher[j] + i;
				//超过z则从a开始
				if (temp > 'z')
				{
					temp -= 26;
				}
			}
			clear[j] = temp;
		}
		printf("\n偏移量%d: ",i);
		//打印出本次移位解密结果
		for (j = 0; j < strlen(cipher); j++)
		{
			printf("%c", clear[j]);
		}
	}
	return 0;
}

运行结果:

****实验Lab0

**出的明文:

when you play the game of thrones you win or you die there is no middle ground.(在权力游戏中,要么赢要么死,没有中间地带。)

小结与讨论:

上述密文的加密过程使用了凯撒密码:凯撒密码的加密原理非常简单,通过移位,使得每个字母有了一个唯一的加密字母。这种加密方法无法抵抗词频分析,暴力攻击即可**。所以在对上述密文行**时,我们通过编程将移位密码所有移位位数的可能性结果全部列出,可以发现在第21次解密即当移位位数为5时可以得到句义完整的明文。

 

2. cipher text

"ryf utxy?"

"ryf utxy," orqf jhqihu. "nx nqww urwz! ax bhgo roogix, trouqyvo - utxix qo yhutqyv oh fryvxihgo chi rylhyx nth tro ohdxutqyv uh tqfx ro ehybxioruqhy! ojxxet, oh r nqox hwf cixyetdry orqf uh dx hyex, qo ry qybxyuqhy hc dry'o uh jixbxyu tqd cihd utqyzqyv. qu qo rwoh ry qycrwwqswx dxryo hc fqoehbxiqyv utru ntqet tx nqotxo uh tqfx. r tgdry sxqyv, trouqyvo, eryyhu ixoqou utx hjjhiugyqul uh ixbxrw tqdoxwc ryf xpjixoo tqo jxiohyrwqul ntqet ehybxioruqhy vqbxo tqd. xbxil uqdx tx nqww vqbx tqdoxwc rnrl."

"ntru fh lhg xpjxeu egou uh uxww lhg?"

txiegwx jhqihu odqwxf.

"r wqx," tx orqf. "ryf sl qu, q otrww zyhn utx uigut!"

代码:

#include<stdio.h>
#include<string.h>
int main() 
{
	//密文
	char cipher[] = "ryf utxy?ryf utxy,orqf jhqihu.nx nqww urwz! ax bhgo roogix, trouqyvo - utxix qo yhutqyv ohfryvxihgo chi rylhyx nth tro ohdxutqyv uh tqfx ro ehybxioruqhy! ojxxet, oh r nqox hwf cixyetdry orqf uh dx hyex, qo ry qybxyuqhy hc dry'o uh jixbxyu tqd cihd utqyzqyv. qu qo rwoh ry qycrwwqswx dxryo hc fqoehbxiqyv utru ntqet tx nqotxo uh tqfx. r tgdry sxqyv, trouqyvo, eryyhu ixoqou utx hjjhiugyqul uh ixbxrw tqdoxwc ryf xpjixoo tqo jxiohyrwqul ntqet ehybxioruqhy vqbxo tqd. xbxil uqdx tx nqww vqbx tqdoxwc rnrl.ntru fh lhg xpjxeu egou uh uxww lhg?txiegwx jhqihu odqwxf.r wqx,tx orqf.ryf sl qu, q otrww zyhn utx uigut!";
	int i;
	//统计频数
	int a[26][3];
	for (int i = 0; i < 26; i++) {
		a[i][1] = 0;
		a[i][2] = i;
	}
	for (int i = 0; i < strlen(cipher); i++) {
		if (cipher[i] >= 97 && cipher[i] <= 122) {
			a[(cipher[i] - 97)][1]++;
		}
	}
	int  j, tmp1, tmp2;
	for (i = 0; i < 25; i++) {
		for (j = 0; j < 25 - i; j++) {
			if (a[j][1] > a[j + 1][1]) {
				tmp1 = a[j][1];
				tmp2 = a[j][2];
				a[j][1] = a[j + 1][1];
				a[j][2] = a[j + 1][2];
				a[j + 1][1] = tmp1;
				a[j + 1][2] = tmp2;
			}
		}
	}

	int b[26][2];
	for (i = 0; i < 25; i++) {
		b[i][1] = a[i][2];
	}
	//输出频数
	char d[26];
	printf("字符:");
	for (i = 0; i < 26; i++) {
		printf("%2c ", a[i][2] + 97);
		d[i] = a[i][2] + 97;
	}
	printf("\n频数:");
	for (i = 0; i < 26; i++) {
		printf("%2d ", a[i][1]);
	}

	//尝试不同的替换方式
	char c[] = "zqjxkvbpgywmfcudlhrsnioate";
	//char dd[] = "kmapszcljbgvnedfiwtrhuyoqx";
	//char dd[] = "kmapszcljbdvnegfwtioyqhrux";
	char dd[] = "kmapzbsjvlndcegfwtioyqhrux";
	printf("\n");

	//进行替换
	for (i = 0; i < strlen(cipher); i++) {
		for (j = 0; j < 26; j++) {
			if (cipher[i] == dd[j]) {
				cipher[i] = c[j];
				break;
			}
		}
	}

	//输出明文
	printf("\n明文:\n");
	for (i = 0; i < strlen(cipher); i++) {
		printf("%c", cipher[i]);
	}
	printf("\n");

	return 0;
}

运行结果:

****实验Lab0

**出的明文:

and then?and then,said poirot.we will talk! je vous assure, hastings - there is nothing sodangerous for anyone who has something to hide as conversation! speech, so a wise old frenchman said to me once, is an invention of man's to prevent him from thinking. it is also an infallible means of discovering that which he wishes to hide. a human being, hastings, cannot resist the opportunity to reveal himself and express his personality which conversation gives him. every time he will give himself away.what do you expect cust to tell you?hercule poirot smiled.a lie,he said.and by it, i shall know the truth!

小结与讨论:

上述密文的加密过程使用了较复杂的替换密码:对字母表中的每一个字母用其他的唯一的不同的一个密文字母代替,即在明文x与密文y之间建立一对一的映射。本题明文与密文的映射函数并不是简单的一次函数,所以需要根据字母或字母组合在密文片段中出现的频率先进行部分猜测。在**明文时,我们首先通过编程计算出字母出现的频率,并将字母按频率从小到大的顺序依次输出。对照英文字母频率表,猜测出密文字母”x”出现频率最高可能对应明文字母”e”。字母组合”utx”、”tx”、以及字母”r”、”q”在英文语段中特殊的用法等帮助我们逐步确定明文和密文之间的替换表,并通过程序一一检验不同的替换方式,最终**出完整的明文。

 

3. Vigenere cipher text

Ivikdkdqmjglpwlzgmpfbjiidbbysljdxfgbiwwehapheysgnccyootstzabcobvrtazeywvwwazaidgazpethpvbpwobvjxgfmdobcgpfkxkszzaigcjrpetacjhuthpvhkjhpzhfpmevzeqsbyomhsdvftasfgztcobzcghfmdobcwvnvbrvkrgxdbmkfbtgbvgmptbvfmtgblbmxzweshgcbyskdtbysfwoarqhcjqeqbcuidcnchwwgnedwihptkqczgdkigdenhpzgigwvtwiasbfhatqijsbcdwzbmpgqkkthtqigmefmjsgislkcfthpvfxlszvhagsmgclhwjcsxmdtrbtiwweghuhpvgxrzcjwhcczzbvpfkvftiwwecyivqjuxchtvatcwvrbhjhpfiltcnywluobyskhaiegbdbbysktkijhatsfgztcobzcgivikvxloazbaxrqeuydfitfbbswihaphpvkthaiuogshprhmwsgnwlwslkctkcquogpggcifdfbyomwsprrldamuwltoavkaxqptonhslywlhsoiszphqfbbrcccrmwwvbcyccwkvxgolvenphmjcejhqfblivmjsmwsvyowicjvgbuhmuogspicogrslrutxbakstrvwkvxg

代码:

#include<stdio.h>
#include<string.h>

int main() {
	char cipher[] = "ivikdkdqmjglpwlzgmpfbjiidbbysljdxfgbiwwehapheysgnccyootstzabcobvrtazeywvwwazaidgazpethpvbpwobvjxgfmdobcgpfkxkszzaigcjrpetacjhuthpvhkjhpzhfpmevzeqsbyomhsdvftasfgztcobzcghfmdobcwvnvbrvkrgxdbmkfbtgbvgmptbvfmtgblbmxzweshgcbyskdtbysfwoarqhcjqeqbcuidcnchwwgnedwihptkqczgdkigdenhpzgigwvtwiasbfhatqijsbcdwzbmpgqkkthtqigmefmjsgislkcfthpvfxlszvhagsmgclhwjcsxmdtrbtiwweghuhpvgxrzcjwhcczzbvpfkvftiwwecyivqjuxchtvatcwvrbhjhpfiltcnywluobyskhaiegbdbbysktkijhatsfgztcobzcgivikvxloazbaxrqeuydfitfbbswihaphpvkthaiuogshprhmwsgnwlwslkctkcquogpggcifdfbyomwsprrldamuwltoavkaxqptonhslywlhsoiszphqfbbrcccrmwwvbcyccwkvxgolvenphmjcejhqfblivmjsmwsvyowicjvgbuhmuogspicogrslrutxbakstrvwkvxg";
	int len, sum, sum2 = 0;

	int i, j;

	//错位值为i时,相同字符的数目
	for (i = 1; i < 10; i++) {
		sum = 0;
		for (j = 0; j < strlen(cipher); j++) {
			if (i + j < strlen(cipher)) {
				if (cipher[j] == cipher[i + j])
					sum++;
			}
			else {
				if (cipher[j] == cipher[strlen(cipher) - i - j])
					sum++;
			}
		}
		if (sum2 < sum) {
			sum2 = sum;
			len = i;
		}
		printf("移位%d的字符相同数:%d\n", i, sum);
	}
	printf("所以,**的长度为:%d\n\n\n", len);  //相同字符数目最多对应的错位值i,即为**的长度

	int count[6][26] = { 0 };
	char count2[6][27];

	//初始化,每个count2[i]都为abcdefghijklmnopqrstuvwxyz
	for (i = 0; i < 6; i++) {
		strcpy_s(count2[i], 27, "abcdefghijklmnopqrstuvwxyz");
	}

	int k;

	//由**第i项加密的字母的频度
	for (i = 0; i < 6; i++) {
		for (j = i; j < strlen(cipher); j = j + 6) {
			count[i][cipher[j] - 97]++;
		}
	}


	char ctmp;
	int tmp;

	//冒泡排序
	for (i = 0; i < 6; i++) {
		for (j = 0; j < 25; j++) {
			for (k = 0; k < 25 - j; k++) {
				if (count[i][k] > count[i][k + 1]) {
					tmp = count[i][k];
					ctmp = count2[i][k];
					count[i][k] = count[i][k + 1];
					count2[i][k] = count2[i][k + 1];
					count[i][k + 1] = tmp;
					count2[i][k + 1] = ctmp;
				}
			}
		}
	}

	for (i = 0; i < 6; i++) {
		printf("由**第%d项加密的字母的频度:\n", i + 1);
		for (j = 0; j < 26; j++) {
			printf("%d%c  ", count[i][j], count2[i][j]);
		}
		printf("\n\n");
	}

	//对应的映射关系,一般来说,频度最高的字母对应的是e
	//t----e  p
	//s----e  o
	//m----e  i
	//v----e  r
	//s----e  o
	//x----e  t
	printf("\n映射关系:\n");
	printf("t----e  p\n");
	printf("s----e  o\n");
	printf("m----e  i\n");
	printf("v----e  r\n");
	printf("s----e  o\n");
	printf("x----e  t\n\n");

	//利用**解密
	for (i = 0; i < 6; i++) {
		for (j = i; j < strlen(cipher); j = j + 6) {
			switch (i) {
			case 0:
				cipher[j] = (cipher[j] - 97 - 15 + 26) % 26 + 97;
				break;
			case 1:
				cipher[j] = (cipher[j] - 97 - 14 + 26) % 26 + 97;
				break;
			case 2:
				cipher[j] = (cipher[j] - 97 - 8 + 26) % 26 + 97;
				break;
			case 3:
				cipher[j] = (cipher[j] - 97 - 17 + 26) % 26 + 97;
				break;
			case 4:
				cipher[j] = (cipher[j] - 97 - 14 + 26) % 26 + 97;
				break;
			case 5:
				cipher[j] = (cipher[j] - 97 - 19 + 26) % 26 + 97;
				break;
			}
		}
	}
	printf("明文为:\n");
	for (i = 0; i < strlen(cipher); i++) {
		printf("%c", cipher[i]);
	}

	printf("\n");
}

运行结果:

****实验Lab0

**出的明文:

Thatprocesssaidistartsuponthesuppositionthatwhenyouhaveeliminatedallwhichisimpossiblethenwhateverremainshoweverimprobablemustbethetruthitmaywellbethatseveralexplanationsremaininwhichcaseonetriestestaftertestuntiloneorotherofthemhasaconvincingamountofsupportwewillnowapplythisprincipletothecaseinpointasitwasfirstpresentedtometherewerethreepossibleexplanationsoftheseclusionorincarcerationofthisgentlemaninanouthouseofhisfathersmansiontherewastheexplanationthathewasinhidingforacrimeorthathewasmadandthattheywishedtoavoidanasylumorthathehadsomediseasewhichcausedhissegregationicouldthinkofnootheradequatesolutionsthesethenhadtobesiftedandbalancedagainsteachother

小结与讨论:

上述密文的加密过程使用了维吉尼亚密码:维吉尼亚密码是一种典型的多表替换密码,可以看成是使用一系列不同移位的凯撒密码组成的密码方案,这样的加密过程中可能会出现同一个明文字母对应多个密文字母或者多个明文字母对应同一个密文字母的情况。**维吉尼亚密码的关键是要先获取**长度:编程选取不同的移位值比较得出在移动多少位置时具有最多的字符相同数。由输出结果可以看出,当移动6个位置时具有最多的相同数,故移位值6就是最可能的**长度值。然后我们需要获取**值:观察第1、第7、第13个......字母,即由**第一项元素加密的这些字母,看哪一个字母出现的频率最高则最可能代替明文中的字母e。重复上述过程我们可以依次找到其他5组的**即移位数,得到最后的**猜想:p o i r o t。

维吉尼亚密码加密有自己优势:在一定程度上改变了密文字母的频率,采用了**在明文上重复书写的原理,这样一个字母可能对应多个替换即多表替换而非一对一的字符替换。但是只要密文足够多,就可以生成合理的统计样本,维吉尼亚密码依然可以通过频率分析被**。

 

4.Rar file without password

代码:

import binascii
import string
tmp=string.printable     #各种打印字符
crc = 0x05665E74   #文件的CRC,0x开头

#文件的内容为3位,所以三层循环遍历
for i in tmp :
    for j in tmp:
        for k in tmp:
            s=str(i)+str(j)+str(k)

            #将其转为无符号整数,与文件的crc比较
            if crc == ((binascii.crc32(bytes(s,'UTF-8'))) & 0xffffffff):

               print("内容:"+s)    #打印文件内容

运行结果:

****实验Lab0

**出的文件内容:

文件内容:77%

小结与讨论:

主要思想:每个不同的文件都有唯一的CRC32值。对于内容相同的文件,它们的CRC32值是一样的。所以我们可以根据CRC32值,暴力**文件的内容,而无需知道压缩密码。

**步骤:

Step 1: 获知文件内容的长度

用WinRAR打开压缩文件,里面会显示文件内容的长度:

****实验Lab0

从截图中红色方框的内容可以看出,文件内容由三个字符组成。

Step 2: 暴力**文件的内容

文件内容只有三个字符,我们只要将所有可能的情况列出来,将其CRC32值与压缩文件比较。一旦相同,就表明这三个字符就是文件的内容。

由此我们借助编程**得到了rate.txt文件的内容。

相关标签: ****