C语言的小算法技巧

最后更新时间:Wed Apr 20 11:21:54 CST 2016


Preface

以下是收集的,并且自己用到过的小技巧集锦,写这个主要是因为,长时间不接触,忘记了很多的小技巧了,等到自己再去使用的时候。。。。天哪,就是折磨人。所以,从这个POST里就开始收集下小“技巧”或者“小算法”。但是,都是很些很简单的东西,也会有复杂的东西。


1. 矩阵上的操作

1. AES的列混合里操作

我们都知道AES加密的过程中需要对进行列混合的运算。在编程实现的时候,有的人的列混合函数写地比较冗长烦琐,但是有点容易理解。在小伙伴的推荐下,看到了这个里面的小技巧。当时是觉得有点难理解,但是理解过后,恍然大悟,觉得谁第一个写这个函数的人好聪明。以后如果可以碰到类似的矩阵操作可以按照这种思想去进行。


2. 代码

列混合的矩阵如下:

02010103030201010103020101010302(4)

代码如下:

#include<stdio.h>


void MixColumns (int intput[4][4],int output[4][4]);

int main()
{
    int intput[4][4];
    int i,j;
    int output[4][4];

    printf("输入为:\n");
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            scanf("%x",&intput[j][i]);
        }
    }
    MixColumns(intput,output);
    printf("输出列混合结果为:\n");
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            printf("%x ",output[i][j]);
        }
        printf("\n");
    }
    return 0;
}


//{0x02}•{0xAF}的运算
//如果0xAF转换成二进制的第一位为1,则向左移位1位,并且和0x1B异或
//如果0xAF转换成二进制的第一位为0,则向左移位1位即可
unsigned char xtime(unsigned char input)  
{
    int temp;
    temp = input<<1;
    if(input & 0x80)
    {
        temp ^= 0x1b;
    }
    return temp;
}

void MixColumns (int intput[4][4],int output[4][4])
{
    int i,j;

    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            output[i][j] = xtime(intput[i%4][j]) ^ (intput[(i+1)%4][j] ^ xtime(intput[(i+1)%4][j]))
                ^ intput[(i+2)%4][j]  
                ^ intput[(i+3)%4][j]; 
        }

    }
}

很明显,这个技巧的核心就是在

output[i][j] = xtime(intput[i%4][j]) ^ (intput[(i+1)%4][j] ^ xtime(intput[(i+1)%4][j]))
                ^ intput[(i+2)%4][j]  
                ^ intput[(i+3)%4][j]; 

解释说明:

xtime(input[i%4][j]) ^ (intput[(i+1)%4][j] ^ xtime(intput[(i+1)%4][j]))
//此句是对0x02和0x03一起的操作,因为矩阵的规律就是0x02和0x03必左右相邻,可以使用取余的方式来让0x02和0x03的操作放在一起进行,就会简单很多

给的范例:


AES列混合样例

运行结果如下:


列混合运行结果

如果还是无法理解,可以根据那个矩阵代个值算下~

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值