您的位置:首页 > 其它

我的C实践(9):位和字节的重排

2016-07-29 00:00 344 查看
位和字节的重排在密码学算法中有广泛的应用。

/* rearran.c:位和字节的重排 */
/* 位反转:以字的中心为对称点进行位反射
例如:  abcd efgh ijkl mnop ABCD EFGH IJKL MNOP
位反转:PONM LKJI HGFE DCBA ponm lkji hgfe dcba  */
unsigned rev(unsigned x){
/* 交换相邻的单个位 */
x=(x & 0x55555555)<<1 | (x & 0xaaaaaaaa)>>1;
/* 交换相邻的2位字段 */
x=(x & 0x33333333)<<2 | (x & 0xcccccccc)>>2;
/* 交换相邻的4位字段 */
x=(x & 0x0f0f0f0f)<<4 | (x & 0xf0f0f0f0)>>4;
/* 交换相邻的8位字段 */
x=(x & 0x00ff00ff)<<8 | (x & 0xff00ff00)>>8;
/* 交换相邻的16位字段 */
x=(x & 0x0000ffff)<<16 | (x & 0xffff0000)>>16;
return x;
}
/* 字节反转:以字的中心为对称点进行字节反射
例如:    abcd efgh ijkl mnop ABCD EFGH IJKL MNOP
字节反转:IJKL MNOP ABCD EFGH ijkl mnop abcd efgh */
unsigned revw(unsigned x){
x=(x & 0x00ff00ff)<<8 | (x & 0xff00ff00)>>8;
x=(x & 0x0000ffff)<<16 | (x & 0xffff0000)>>16;
return x;
}
/* 位混洗:将右半字的各个位相间地插入到左半字中,尾部的位仍然保留在尾部
例如:abcd efgh ijkl mnop ABCD EFGH IJKL MNOP
混洗:aAbB cCdD eEfF gGhH iIjJ kKlL mMnN oOpP */
unsigned shuffling(unsigned x){
unsigned t;
/* 初始:abcd efgh ijkl mnop ABCD EFGH IJKL MNOP */
/*       abcd efgh ABCD EFGH ijkl mnop IJKL MNOP */
t=(x ^ (x>>8)) & 0x0000ff00;  x=x ^ t ^ (t<<8);
/*       abcd ABCD efgh EFGH ijkl IJKL mnop MNOP */
t=(x ^ (x>>4)) & 0x00f000f0;  x=x ^ t ^ (t<<4);
/*       abAB cdCD efEf ghGH ijIJ klKL mnMN opOP */
t=(x ^ (x>>2)) & 0x0c0c0c0c;  x=x ^ t ^ (t<<2);
/*       aAbB cCdD eEfF gGhH iIjJ kKlL mMnN oOpP */
t=(x ^ (x>>1)) & 0x22222222;  x=x ^ t ^ (t<<1);
return x;
}
/* 逆混洗 */
unsigned unshuffling(unsigned x){
/* 以相反的顺序进行交换即可实现逆混洗 */
t=(x ^ (x>>1)) & 0x22222222;  x=x ^ t ^ (t<<1);
t=(x ^ (x>>2)) & 0x0c0c0c0c;  x=x ^ t ^ (t<<2);
t=(x ^ (x>>4)) & 0x00f000f0;  x=x ^ t ^ (t<<4);
t=(x ^ (x>>8)) & 0x0000ff00;  x=x ^ t ^ (t<<8);
}
/* 位矩阵转置:转置8*8位的矩阵,注意算法以“左上-右下”对角线为基准进行转置
(1) 看作16个2*2位矩阵:转置这些2*2位矩阵;
(2) 看作4个2*2子矩阵:子矩阵的元素是2*2位矩阵,转置这些2*2子矩阵;
(3) 看作1个2*2子矩阵:子矩阵的元素是4*4位矩阵,转置这个2*2子矩阵。
0 1 2 3 4 5 6 7      0 8 2 a 4 c 6 e      0 8 g o 4 c k s      0 8 g o w E M U
8 9 a b c d e f      1 9 3 b 5 d 7 f      1 9 h p 5 d l t      1 9 h p x F N V
g h i j k l m n      g o i q k s m u      2 a i q 6 e m u      2 a i q y G O W
o p q r s t u v (1)  h p j r l t n v (2)  3 b j r 7 f n v (3)  3 b j r z H P X
w x y z A B C D ===> w E y G A I C K ===> w E M U A I Q Y ===> 4 c k s A I Q Y
E F G H I J K L      x F Z H B J D L      x F N V B J R Z      5 d l t B J R Z
M N O P Q R S T      M U O W Q Y S $      Y G O W C K S $      6 e m u C K S $
U V W X Y Z $ .      N V P X R Z T .      z H P X D L T .      7 f n v D L T .

参数A是8m*8n位源矩阵中的8*8子矩阵的第一个字节的地址,B是8n*8m位目标矩阵中的8*8子矩阵的
第一个字节的地址。整个源矩阵是8m*n字节,目标矩阵是8n*m字节 */
void transpose8(unsigned char A[8], int m, int n, unsigned char B[8]){
unsigned x,y,t;

/* 载入数组,并把它装入到x和y中 */
x=(A[0]<<24) | (A[m]<<16) | (A[2*m]<<8) | A[3*m];
y=(A[4*m]<<24) | (A[5*m]<<16) | (A[6*m]<<8) | A[7*m];

/* 交换字中(从右编号)第1位和第8位、第3位和第10位、第5位和第12位,以此类推;
而不移动第0位、第2位、第4位,以此类推。
例如:  01234567 89abcdef ghijklmn opqrstuv
交换后:082a4c6e 193b5d7f goiqksmu hpjrltnv  */
t=(x ^ (x>>7) & 0x00aa00aa;  x=x ^ t ^ (t<<7);
t=(y ^ (y>>7) & 0x00aa00aa;  y=y ^ t ^ (t<<7);

t=(x ^ (x>>14) & 0x0000cccc;  x=x ^ t ^ (t<<14);
t=(x ^ (y>>14) & 0x0000cccc;  y=y ^ t ^ (t<<14);

t=(x & 0xf0f0f0f0) | ((y>>4) & 0x0f0f0f0f);
y=((x<<4) & 0xf0f0f0f0) | (y & 0x0f0f0f0f);
x=t;

B[0]=x>>24;  B
=x>>16;  B[2*n]=x>>8;  B[3*n]=x;
B[4*n]=y>>24;  B[5*n]=y>>16;  B[6*n]=y>>8;  B[7*n]=y;
}
/* 转置32*32位矩阵 */
void transpose32(unsigned A[32]){
int j,k;
unsigned m,t;

m=0x0000ffff;
for(j=16; j!=0; j=j>>1, m=m^(m<<j)){
for(k=0; k<32; k=(k+j+1) & ~j){
t=(A[k] ^ (A[k+j]>>j)) & m;
A[k]=A[k] ^ t;
A[k+j]=A[k+j] ^ (t<<j);
}
}
}
/* 位压缩:根据一个掩码m对字x进行压缩,即将x中所有与m中的1位对应的位移动到右端,
从而压缩成一个新字,例如
给定字: abcd efgh ijkl mnop qrst uvwx yzAB CDEF
掩码:   0000 1111 0011 0011 1010 1010 0101 0101
压缩后: 0000 0000 0000 0000 efgh klop qsuw zBDF  */
unsigned compress(unsigned x,unsigned m){
unsigned r,s,b; /* 结果、移动位数、掩码位 */

r=0;
s=0;
do{
b=m & 1;  /* 获取m的当前位 */
/* b为1时x的相应位就要放入r中,b为0时x的相应位不放入r中 */
r=r | ((x & b)<<s);
s=s+b;
x=x>>1;
m=m>>1;
}while(x!=0);
return r;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: