N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列。设计加密解密算法,且要求K<=15*N.

如果是:

  • N<=16,要求K<=16*N.
  • N<=16,要求K<=10*N.
  • N<=64,要求K<=15*N.
#include <iostream>
using namespace std;

void printArray(int* arr, int len) {
	if (!arr) {
		return;
	}
	for (int i = 0; i < len; ++i) {
		cout << arr[i] << " ";
	}
	cout << endl;
}

int cmp(const void *a, const void *b) {
	int aa = (*(const int*) a) >> 4;
	int bb = (*(const int*) b) >> 4;
	return aa - bb;
}

int cmp1(const void *a, const void *b) {
	int aa = (*(const int*) a) >> 2;
	int bb = (*(const int*) b) >> 2;
	return aa - bb;
}

void disorder(int* arr, int len) {
	srand((int) time(NULL));
	for (int i = 0; i < len; i++) {
		int tmp = rand() % len;
		swap(arr[i], arr[tmp]);
	}
}

int* encrypt1(int* arr, int len, int k) {
	int id = 0;

	int* encryptArr = new int[k * len];
	memset(encryptArr, 0, sizeof(int) * k * len);
	for (int i = 0; i < len; ++i) {
		int index = (i << 4);
		int prev = arr[i] >> 4;
		int last = arr[i] & 15;
		for (int j = 0; j < k - 8; ++j, id++) {
			encryptArr[id] = index | prev;
		}
		for (int j = 0; j < 8; ++j, id++) {
			encryptArr[id] = index | last;
		}
	}

//	printArray(encryptArr, k * len);
	disorder(encryptArr, k * len);

	return encryptArr;
}

int* encrypt2(int* arr, int len, int k) {
	int id = 0;

	int* encryptArr = new int[k * len];
	memset(encryptArr, 0, sizeof(int) * k * len);
	for (int i = 0; i < len; ++i) {
		int index = (i << 2);
		int data1 = arr[i] >> 6;
		int data2 = (arr[i] >> 4) & 3;
		int data3 = (arr[i] >> 2) & 3;
		int data4 = arr[i] & 3;

		encryptArr[id++] = index | data1;

		for (int j = 0; j < 2; ++j, id++) {
			encryptArr[id] = index | data2;
		}

		for (int j = 0; j < 4; ++j, id++) {
			encryptArr[id] = index | data3;
		}

		for (int j = 0; j < 8; ++j, id++) {
			encryptArr[id] = index | data4;
		}
	}

//	printArray(encryptArr, k * len);
	disorder(encryptArr, k * len);

	return encryptArr;
}

int* decrypt1(int* encryptArr, int len, int k) {
	qsort(encryptArr, k * len, sizeof(int), cmp);
//	printArray(encryptArr, k * len);

	int* decryptArr = new int[len];
	memset(decryptArr, 0, sizeof(int) * len);
	int prev = 0;
	int last = 0;
	int count1 = 0;
	int count2 = 0;
	int index = 0;
	for (int i = 0; i < k * len; i += k) {
		prev = encryptArr[i];
		count1 = 1;
		count2 = 0;
		for (int j = i + 1; j < i + k; ++j) {
			if (prev == encryptArr[j]) {
				count1++;
			} else {
				last = encryptArr[j];
				count2++;
			}
		}
		if (count1 > k - 8) {
			if (count1 == k) {	//加密前prev,last相同
				last = prev;
			}
			swap(last, prev);
		} else if (count2 > k - 8) {
			if (count2 == k) {
				prev = last;
			}
		}
		prev &= 15;
		last &= 15;
		prev <<= 4;
		decryptArr[index++] = prev | last;
	}

	return decryptArr;
}

int* decrypt2(int* encryptArr, int len, int k) {
	qsort(encryptArr, k * len, sizeof(int), cmp1);
//	printArray(encryptArr, k * len);

	int* decryptArr = new int[len];
	memset(decryptArr, 0, sizeof(int) * len);
	int* data = new int[4];
	int* count = new int[4];
	int index = 0;
	int id = 1;
	for (int i = 0; i < k * len; i += k) {
		memset(data, -1, 4 * sizeof(int));
		memset(count, 0, 4 * sizeof(int));
		data[0] = encryptArr[i];
		count[0] = 1;
		id = 1;
		for (int j = i + 1; j < i + k; ++j) {
			if (encryptArr[j] == data[0]) {
				count[0]++;
			} else if (encryptArr[j] == data[1]) {
				count[1]++;
			} else if (encryptArr[j] == data[2]) {
				count[2]++;
			} else if (encryptArr[j] == data[3]) {
				count[3]++;
			} else if (id < 4) {
				data[id] = encryptArr[j];
				count[id]++;
				id++;
			}
		}
		int data1 = -1;
		int data2 = -1;
		int data3 = -1;
		int data4 = -1;
		for (int i = 0; i < 4; ++i) {
			if (!count[i]) {
				break;
			}
			switch (count[i]) {
			case 1:
				data1 = data[i] & 3;
				break;
			case 2:
				data2 = data[i] & 3;
				break;
			case 4:
				data3 = data[i] & 3;
				break;
			case 8:
				data4 = data[i] & 3;
				break;
			case 3:
				data1 = data2 = data[i] & 3;
				break;
			case 5:
				data1 = data3 = data[i] & 3;
				break;
			case 9:
				data1 = data4 = data[i] & 3;
				break;
			case 6:
				data2 = data3 = data[i] & 3;
				break;
			case 10:
				data2 = data4 = data[i] & 3;
				break;
			case 12:
				data3 = data4 = data[i] & 3;
				break;
			case 7:
				data1 = data2 = data3 = data[i] & 3;
				break;
			case 11:
				data1 = data2 = data4 = data[i] & 3;
				break;
			case 13:
				data1 = data3 = data4 = data[i] & 3;
				break;
			case 14:
				data2 = data3 = data4 = data[i] & 3;
				break;
			}

		}
		decryptArr[index] |= data1 << 6;
		decryptArr[index] |= data2 << 4;
		decryptArr[index] |= data3 << 2;
		decryptArr[index] |= data4;

		index++;

	}
	return decryptArr;
}

int* encryptChoice(int* arr, int len, int n, int k) {
	int* encryptArr = NULL;
	if (n == 16) {
		if (len > n) {
			return NULL;
		}
		if (k == 16) {
			k = 12;
			encryptArr = encrypt1(arr, len, k);
		} else if (k == 10) {
			encryptArr = encrypt1(arr, len, k);
		}
	} else if (n == 64 && k == 15) {
		encryptArr = encrypt2(arr, len, k);
	}

	if (encryptArr) {
		cout << "n,k: " << n << "," << k << endl;
		cout << "加密数组:" << endl;
		printArray(encryptArr, k * len);
	}

	return encryptArr;
}

void decryptChoice(int* encryptArr, int len, int n, int k) {
	int* decryptArr = NULL;
	if (n == 16) {
		//int 是32bit
		if (len > n) {
			return;
		}
		if (k == 16) {
			k = 12;
			decryptArr = decrypt1(encryptArr, len, k);
		} else if (k == 10) {
			decryptArr = decrypt1(encryptArr, len, k);
		}
	} else if (n == 64 && k == 15) {
		decryptArr = decrypt2(encryptArr, len, k);
	}

	if (decryptArr) {
		cout << "解密数组:" << endl;
		printArray(decryptArr, len);
	}
}
int main() {
	int arr1[] =
			{ 12, 20, 51, 4, 7, 48, 32, 13, 41, 35, 44, 67, 55, 34, 54, 63 };
	int len = sizeof(arr1) / sizeof(int);

	int k = 16;
	int n = 16;
	int* encryptArr = NULL;
	encryptArr = encryptChoice(arr1, len, n, k);
	decryptChoice(encryptArr, len, n, k);

	k = 10;
	encryptArr = encryptChoice(arr1, len, n, k);
	decryptChoice(encryptArr, len, n, k);

	k = 15;
	n = 64;
	encryptArr = encryptChoice(arr1, len, n, k);
	decryptChoice(encryptArr, len, n, k);
	return 0;
}

N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列。设计加密解密算法,且要求K<=15*N.的更多相关文章

  1. memory barrier 内存屏障 编译器导致的乱序

    小结: 1. 很多时候,编译器和 CPU 引起内存乱序访问不会带来什么问题,但一些特殊情况下,程序逻辑的正确性依赖于内存访问顺序,这时候内存乱序访问会带来逻辑上的错误, 2. https://gith ...

  2. Grafana Mimir:支持乱序的指标采集

    Grafana Mimir:支持乱序的指标采集 译自:New in Grafana Mimir: Introducing out-of-order sample ingestion 很早之前在使用th ...

  3. Lintcode--003(乱序字符串)

    给出一个字符串数组S,找到其中所有的乱序字符串(Anagram).如果一个字符串是乱序字符串,那么他存在一个字母集合相同,但顺序不同的字符串也在S中. 注意事项 所有的字符串都只包含小写字母   样例 ...

  4. tf.train.batch的偶尔乱序问题

    tf.train.batch的偶尔乱序问题 觉得有用的话,欢迎一起讨论相互学习~Follow Me tf.train.batch的偶尔乱序问题 我们在通过tf.Reader读取文件后,都需要用batc ...

  5. 网络损伤仪WANsim中的乱序功能

    乱序 乱序功能需要指定每个帧 发生乱序的概率,以及新的帧的位置相较于原来位置的时间范围. 乱序的概率范围是0%~20%,颗粒度是0.001%.Delay的设置范围为 0s~10s,颗粒度为0.1 ms ...

  6. [补题]找到原序列长度k的子序列中字典序最小的那个(单调栈)

    题意 题目如题,输入序列只包含小写字母,数据范围0<k<=len<=500000. 例: 输入:helloworld 输出:ellld 题解 使用单调栈.当已删掉n-k个字符,输出栈 ...

  7. [转载]排序:长度为n的数组乱序存放着0至n-1. 现在只能进行0与其他数的swap

    长度为n的数组乱序存放着0至n-1. 现在只能进行0与其他数的swap 请设计并实现排序. google笔试小题.题目来源:http://wenku.baidu.com/view/5aa818dda5 ...

  8. 在一个文件中有10G个整数,乱序排列,要求找出中位数

     题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存). ...

  9. 腾讯面试题:10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。

    腾讯面试题:10G 个整数,乱序排列,要求找出中位数.内存限制为 2G. 题目和基本思路都来源网上,本人加以整理. 题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只 ...

随机推荐

  1. 我常用的css基础

    mkdir 创建文件夹touch 创建文件mode:'history' ----------------------------------------------------------去除# di ...

  2. [SDOI 2009]HH去散步

    Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又 ...

  3. 计蒜客NOIP模拟赛D2T2 直线的交点

    伦伦刚刚在高中学习了解析几何,学会了计算两条直线的交点.这天,老师给她布置了一道作业.在平面上有 nnn 条直线,他们之间有若干交点.给定一对平板(两条平行的直线),问这有多少对直线,他们的交点在这一 ...

  4. [HNOI2008]越狱

    题目描述 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱 输入输出格式 输入 ...

  5. C++Primer学习——各种运算符

    前缀递增和后缀递增 class NewInt { public: NewInt():RootInt(0){}; NewInt(int IniInt):RootInt(IniInt){}; NewInt ...

  6. [Noi2013]书法家

    来自FallDream的博客,未经允许,请勿转载,谢谢. 小E同学非常喜欢书法,他听说NOI2013已经开始了,想题一幅“NOI”的字送给大家. 小E有一张非常神奇的纸,纸可以用一个n 行m 列的二维 ...

  7. [Codeforces]860E Arkady and a Nobody-men

    屯一个虚树的板子,顺便总结一下这样的题型. Description 给定一棵n个节点的有根树,在输入数据通过给出每个节点的父亲来表示这棵树.若某个节点的父亲为0,那么该节点即为根.现在对于每个点,询问 ...

  8. Thinkphp中的U函数(Thinkphp3.2.3版本)

    U函数的作用是根据当前的URL设置生成对应的URL地址,使用U函数可以确保项目在移植过程中不受环境的影响. U方法的定义规则如下(方括号内参数根据实际应用决定): U('地址表达式',['参数'],[ ...

  9. 第一节mysql 安装

    1 安装之前的检查 先要检查Linux系统中是否已经安装了MySQL,输入命令尝试打开MySQL服务: 输入密码后,如果出现以下提示,则说明系统中已经安装有 MySQL: 如果提示是这样的,则说明系统 ...

  10. Linux配置服务器的一点总结

    一.Linux初始化服务 首先搞清楚四个概念: 进程:正在运行的程序,有自己独立的内存空间. 线程:是进程的下属单位,开销较进程小,没有自己独立的内存空间. 作业:由一系列进程组成,来完成某一项任务. ...