2011//11/21日修改的分组密码作业

#include<stdio.h>
#include <stdlib.h>
#define N 5  //矩阵阶数
#define p 29     //模数 ,最好是个素数
int hanglieshi(int n,int x[N][N]);
int yuzishi(int n,int x[N][N],int i,int j);
void Inverse(int n, int x[N][N] , int y[N][N]);
void Multiply(int n,int temp[N][N],int x[N][N],int y[N][N]);
void Print(int n,int temp[N][N]);

int  main()
{
 unsigned int s; //密钥种子
 printf("Please input a srand seed:");
 scanf("%u",&s);
 srand(s); //初始化随机数
 int i,j;
 int A[N][N],B[N][N],An[N][N],Bn[N][N];
 for(i=0;i<N;i++)
 {
  for(j=0;j<N;j++)
  {
   int temp=rand();//产生一个0-127的正的随机数
   A[i][j]=temp%p;
   temp=rand();
   B[i][j]=temp%p;
  }
 }//随机产生2个密钥矩阵
 if(hanglieshi(N,A)==0||hanglieshi(N,B)==0)
 {
  printf("不存在逆矩阵\n");
  exit(0);
 }
 //printf("密钥矩阵A:\n");
 //Print(N,A);
 //printf("密钥矩阵B:\n");
 //Print(N,B);
 Inverse(N,A,An);
 //printf("A的逆矩阵An:\n");
 //Print(N,An);
 Inverse(N,B,Bn);
 //printf("B的逆矩阵Bn:\n");
 //Print(N,Bn);

//测试矩阵(明文)
 int T[N][N]={{1,2,3,4,5},
    {5,6,7,8,9},
    {0,10,2,3,1},
    {20,21,22,23,24},
    {12,12,14,15,16}};
 printf("ming wen matrix:\n");
 Print(N,T);
 int tp1[N][N],tp2[N][N],tp3[N][N],tp4[N][N];

 Multiply(N,tp1,A,T);
 Multiply(N,tp2,tp1,B);
 printf("After encryption:\n");
 Print(N,tp2);

 Multiply(N,tp3,An,tp2);
 Multiply(N,tp4,tp3,Bn);
 printf("After decryption:\n");
 Print(N,tp4);
 return 0;
}


int hanglieshi(int n,int x[N][N])
{
 int h=0;
 int i=0;
 int yuzishi(int n,int x[N][N],int i,int j);
 if (n==2)
  h=x[0][0]*x[1][1]-x[0][1]*x[1][0];
 else
  for(i=0;i<n;i++)
   h=h+x[0][i]*yuzishi(n,x,0,i);
 return h%p;
}

int yuzishi(int n,int x[N][N],int i,int j)
{
 int a=1,c=0,d=0;
 int h=0;
 int y[N][N];
 for(c=0;c<i;c++)
 {
  for(d=0;d<j;d++)
   y[c][d]=x[c][d];
  for(d=j;d<n-1;d++)
   y[c][d]=x[c][d+1];
 }
 for(c=i;c<n-1;c++)
 {
  for(d=0;d<j;d++)
   y[c][d]=x[c+1][d];
  for(d=j;d<n-1;d++)
   y[c][d]=x[c+1][d+1];
 }//矩阵分成四块进行计算
 
 h=hanglieshi((n-1),y);
 if((i+j)%2!=0)
  h=-h;//计算行列式的符号
 return h%p;
}

int Ni(int n)
{
  int i=0;
  for(i=0;i<p;i++)
  {
   if((i*n)%p==1)
    return i;
  }
  if(i==p)
   printf("%d no Inverse!\n",n);
}//求 h 模 p 下的乘法逆元
void Inverse(int n, int x[N][N] , int y[N][N])
{
 int i,j;
 int h=hanglieshi(n ,x);
 while(h<0) h+=p;
 for(i=0;i<n;i++)
 {
  for(j=0;j<n;j++)
  int temp=yuzishi(n,x,j,i);
   while(temp<0)
    temp+=p;
   y[i][j]=(temp*Ni(h))%p;  //对应代数余子式的转置
  }
 }
}


void Multiply(int n,int temp[N][N],int x[N][N],int y[N][N])
{
 int i,j,k;
 for(i=0;i<n;i++)
  for(j=0;j<n;j++)
  
   temp[i][j]=0;   
   for(k=0;k<n;k++)
   {
    temp[i][j]+=x[i][k]*y[k][j];
   
   temp[i][j]%=p;
  }
}

void Print(int n,int temp[N][N])
{
 int i,j;
 for(i=0;i<n;i++)
 {
  for(j=0;j<n;j++)
  {
   printf("%d\t",(int )temp[i][j]);
  }
 printf("\n\n");
 }
printf("\n\n");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值