N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列。设计加密解密算法,且要求K<=15*N.
2017-01-13 23:11
483 查看
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.
如果是:
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.
- 陈利人 面试题 对于一个n位正整数a,去掉其中任意k(k<=n)个数字后,剩下的数字按原次序排列可以组成一个新的正整数。设计一个删数算法,使得剩下的数字组成的正整数最小。
- 对于一个n位正整数a,去掉其中任意k(k<=n)个数字后,剩下的数字按原次序排列可以组成一个新的正整数。设计一个删数算法,使得剩下的数字组成的正整数最小。例如,a=13243221,k=5,输出:12
- 每天学习一算法系列(29)(有两个序列a,b,大小都为n,序列元素的值任意整数,无序;要求:通过交换a,b 中的元素,使[序列a 元素的和]与[序列b 元素的和]之间的差最小)
- 给定整数a1、a2、a3、...、an,判断是否可以从中选出若干个数,使得它们的和等于k(k任意给定,且满足-10^8 <= k <= 10^8)。
- 设n个不同的整数排好序后存于T[1..n]中,若存在一个下标i(1≤ i ≤ n),使得T[i]=i。试设计一个有效算法找到这个下标,要求算法在最坏情形下的计算时间为O(log n)
- 算法 - 有一个连续整数序列,里面随机存放的是0到99这100个不重复的整数,要求对该序列排序。
- 给定整数a1、a2、a3、...、an,判断是否可以从中选出若干个数,使得它们的和等于k(k任意给定,且满足-10^8 <= k <= 10^8)。
- 通过代理截取并修改非对称密钥加密信息 加密、解密算法总的来说可以分称对称密钥加密以及非对称密钥加密算法。 对称密钥加密算法要求加密和解密都用同一把密钥。这可能是对称密码体制的主要弱点(为了让对方能够
- n个无序整数,已知第i个数在排好序的序列中的位置为j,满足|i-j|<=K,请设计一种排序算法,对该序列进行排序。注:算法时间复杂度为O(nlgn)的得0分,复杂度为O(nk) 的得两分,总分是20分
- 设定二维整数数组B[0..m-1,0..n-1]的数据在行,列方向上都按从小到大的顺序排序,且整形变量x中的数据在B中存在。设计一个算法,找出一对满足B[i][j]=x的I,j值,要求比较次数不超过m
- 如何设计一个高效算法从N个正整数中,随机选取n个不同的随机数 n<=N
- 一个正整数有可能可以表示为n(n>=2)个连续的正整数之和,如:15=1+2+3+4+5,15=4+5+6,15=7+8 请编写程序,根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列。
- leetcode:Merge k Sorted Lists(按大小顺序连接k个链表)【面试算法题】
- Problem Description 有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序。 Input 输入数据包含多个测试实例,每组数据由两行组成,第一行是n和m,第二行是已经有序的n个数的数列。n和m同时为0标示输入数
- 给定一个数组,要求把数组内元素的顺序随机打乱,然后输出,主要是要保证效率。
- 12、一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。 请设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。
- 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所 有偶数位于数组的后半部分。要求时间复杂度为O(n)。
- 一串首尾相连的珠子(m个),有n种颜色(n<=10) 设计一种算法去除其中一段,要求包含所有的N种颜色
- 一串首尾相连的珠子(m 个),有N 种颜色(N<=10),设计一个算法,取出其中一段,要求包含所有N 中颜色,并使长度最短。并分析时间复杂度与空间复杂度。