效果
![](https://i-blog.csdnimg.cn/blog_migrate/45d99ba5acaa20b729bd160850788a98.png)
代码
#include<stdio.h>
int SBox[16][16];
int M_x = 283;
int M_x_set[30] = {283,285,299,301,313,319,333,351,355,357,361,369,375,379,391,395,397,415,419,425,433,445,451,463,471,477,487,499,501,505};
int Len_M_x_set = 30;
char dec2Hex(int n);
void init();
void exgcd();
int numb_bits(int v);
int polydivide(int a, int b, int* remainder);
int polyMulti(int a, int b);
int Ext_Euclid(int a, int b);
void transforms(int* c);
int transform(int num, int* c);
int encrypt(int clear);
void search_c(int *c_array, int *pos);
void ferfect_c();
void show_c();
void decto2(int* c, int flag);
int main() {
show_c();
return 0;
}
int encrypt(int clear) {
return SBox[clear / 16][clear % 16];
}
void search_c(int* c_array, int *pos){
int c[8], flag;
for (int i = 0; i < 256;i++) {
decto2(c, i);
init();
exgcd();
transforms(c);
flag = 0;
for (flag; flag< 256;flag++) {
if (flag == encrypt(flag) || 255 - flag == encrypt(flag)) break;
}
if(flag==256) c_array[++(*pos)] = i;
}
}
void ferfect_c(){
int c_array[255], perfect_c_0_1[16][16], pos;
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
perfect_c_0_1[i][j] = 0;
}
}
for (int i = 0; i < Len_M_x_set; i++) {
pos = -1;
search_c(c_array, &pos);
for (int j = 0; j <= pos; j++) {
perfect_c_0_1[c_array[j] / 16][c_array[j] % 16]++;
}
}
printf("perfect_c_0_1矩阵展示:");
for (int i = 0; i < 16; i++) {
printf("\n");
for (int j = 0; j < 16; j++) {
printf("%d ", perfect_c_0_1[i][j]);
}
}
}
void show_c() {
int c_array[255], c_0_1[16][16], pos = -1;
search_c(c_array, &pos);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
c_0_1[i][j] = 0;
}
}
for (int i = 0; i <= pos; i++) {
c_0_1[c_array[i] / 16][c_array[i] % 16] = 1;
}
int m_x[9];
for (int i = 8; i >= 0;i--) {
m_x[i] = M_x % 2;
M_x = (M_x - M_x % 2) / 2;
}
printf("\nm_x多项式:");
for (int i = 0; i < 9; i++) {
printf("%d ",m_x[i]);
}
printf("\n符合条件的c值共有 %d 个", pos + 1);
printf("\nc_0_1矩阵展示:");
for (int i = 0; i < 16; i++) {
printf("\n");
for (int j = 0; j < 16; j++) {
printf("%d ", c_0_1[i][j]);
}
}
}
void decto2(int *c, int flag) {
for (int i = 7; i >= 0;i--) {
c[i] = flag % 2;
flag = (flag - flag % 2) / 2;
}
}
char dec2Hex(int n) {
if (n >= 0 && n <= 9)return 48 + n;
switch (n) {
case 10:return 'A'; break;
case 11:return 'B'; break;
case 12:return 'C'; break;
case 13:return 'D'; break;
case 14:return 'E'; break;
case 15:return 'F'; break;
}
return ' ';
}
void init() {
for (int i = 0; i < 16; i++) {
if (i != 0)SBox[i][0] = SBox[i - 1][15] + 1;
for (int j = 1; j < 16; j++) {
SBox[i][j] = SBox[i][j - 1] + 1;
}
}
}
void exgcd() {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
SBox[i][j] = Ext_Euclid(SBox[i][j], M_x);
}
}
}
int numb_bits(int v)
{
int count = 0;
while (v > 0)
{
v = v >> 1;
count++;
}
return count;
}
int polydivide(int a, int b, int* remainder)
{
int tmp;
int c = numb_bits(a) - numb_bits(b);
int value = 0;
while (c >= 0)
{
value = (1 << c) | value;
tmp = b;
tmp = tmp << c;
a = a ^ tmp;
c = numb_bits(a) - numb_bits(b);
}
*remainder = a;
return value;
}
int polyMulti(int a, int b)
{
int value = a;
int result = a;
int r;
if (a == 0 || b == 0)
return 0;
r = b % 2;
b = b / 2;
if (!r)
result = 0;
while (b)
{
r = b % 2;
b = b / 2;
if (value >> 7)
value = (value << 1) & 0xff ^ 27;
else
value = (value << 1) & 0xff;
if (r)
result = result ^ value;
}
return result;
}
int Ext_Euclid(int a, int b)
{
int tmp;
if (a < b)
{
tmp = a;
a = b;
b = tmp;
}
int x0 = 1, y0 = 0, x1 = 0, y1 = 1;
int tmp1, tmp2;
int r1 = a, r2 = b, q1;
int i = 1;
while (r2)
{
tmp1 = r2;
q1 = polydivide(r1, r2, &r2);
r1 = tmp1;
tmp1 = x1;
tmp2 = y1;
x1 = x0 ^ polyMulti(q1, x1);
y1 = y0 ^ polyMulti(q1, y1);
x0 = tmp1;
y0 = tmp2;
i++;
}
return y0;
}
void transforms(int *c) {
for (int i = 0, j = 0; i < 16; i++) {
for (j = 0; j < 16; j++) {
SBox[i][j] = transform(SBox[i][j], c);
}
}
}
int transform(int num, int *c) {
int n[8];
int b[8];
int i = 0;
for (i = 0; i < 8; i++) {
n[i] = num % 2;
num /= 2;
}
int j = 1;
for (i = 0, num = 0; i < 8; i++) {
b[i] = n[i] ^ n[(i + 4) % 8]
^ n[(i + 5) % 8]
^ n[(i + 6) % 8]
^ n[(i + 7) % 8]
^ c[i];
num += b[i] * j;
j *= 2;
}
return num;
}