按位逻辑运算:
-
按位与运算符(&)
运算规则:只有两个数的二进制同时为1,结果才为1,否则为0。(负数按补码形式参加按位与运算)
即 0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1。任何值 & 1,为任何数(不变); & 0,为0。
-
按位或运算符(|)
运算规则:参加运算的两个数只要两个数中的一个为1,结果就为1。
即 0 | 0= 0 , 1 | 0= 1 , 0 | 1= 1 , 1 | 1= 1 。任何值 | 0,为任何数(不变);|1,为1。
-
异或运算符(^)
运算规则:参加运算的两个数,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
即 0 ^ 0=0 , 0 ^ 1= 1 , 1 ^ 0= 1 , 1 ^ 1= 0 。任何值 ^ 0,为任何数(不变);^ 1,为取反。
x | (x >> 1)与lo ^ (lo >> 1)区别?
- ^能保持原始值(不变或取反) ;
- |1,为1,丢失了原始信息。
实际应用1
//奇数位为1,以1位为单位提取奇偶位
0xAAAAAAAA = 10101010101010101010101010101010
0x55555555 = 01010101010101010101010101010101
//以“2位”为单位提取奇偶位
0xCCCCCCCC = 11001100110011001100110011001100
0x33333333 = 00110011001100110011001100110011
//以“8位”为单位提取奇偶位
0xF0F0F0F0 = 11110000111100001111000011110000
0x0F0F0F0F = 00001111000011110000111100001111
//以“16位”为单位提取奇偶位
0xFFFF0000 = 11111111111111110000000000000000
0x0000FFFF = 00000000000000001111111111111111
code
D:\data\vs\AEADASCON\ascon_opt32\opt32
#define COMPRESS_LONG(x) {\
x &= 0x55555555;\
x = (x | (x >> 1)) & 0x33333333;\
x = (x | (x >> 2)) & 0x0f0f0f0f;\
x = (x | (x >> 4)) & 0x00ff00ff;\
x = (x | (x >> 8)) & 0x0000ffff;\
}
https://editor.csdn.net/md/?articleId=104864566
将u32分解成两个u16,在实现过程中使用了u32类型数据。
实际应用2
D:\data\20200206\LWC\asconLWC\ascon-c-master\crypto_aead\ascon128v12\bi32_lowreg**
//endian.h
#ifndef ENDIAN_H_
#define ENDIAN_H_
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
// macros for big endian machines
#define U64BIG(x) (x)
#define U32BIG(x) (x)
#define U16BIG(x) (x)
#elif defined(_MSC_VER) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
// macros for little endian machines
#define U64BIG(x) \
((((x) & 0x00000000000000FFULL) << 56) | (((x) & 0x000000000000FF00ULL) << 40) | \
(((x) & 0x0000000000FF0000ULL) << 24) | (((x) & 0x00000000FF000000ULL) << 8) | \
(((x) & 0x000000FF00000000ULL) >> 8) | (((x) & 0x0000FF0000000000ULL) >> 24) | \
(((x) & 0x00FF000000000000ULL) >> 40) | (((x) & 0xFF00000000000000ULL) >> 56))
#define U32BIG(x) \
((((x) & 0x000000FF) << 24) | (((x) & 0x0000FF00) << 8) | \
(((x) & 0x00FF0000) >> 8) | (((x) & 0xFF000000) >> 24))
#define U16BIG(x) \
((((x) & 0x00FF) << 8) | (((x) & 0xFF00) >> 8))
#else
#error "ascon byte order macros not defined in endian.h"
#endif
#endif // ENDIAN_H_
typedef struct {
u32 e;
u32 o;
} u32_2;
// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002
#define to_bit_interleaving(out, in) \
do { \
u32 hi = (in) >> 32; \
u32 lo = (u32)(in); \
u32 r0, r1; \
r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); \
r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); \
r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); \
r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); \
r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); \
r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); \
r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); \
r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); \
(out).e = (lo & 0x0000FFFF) | (hi << 16); \
(out).o = (lo >> 16) | (hi & 0xFFFF0000); \
} while (0)
// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002
#define from_bit_interleaving(out, in) \
do { \
u32 lo = ((in).e & 0x0000FFFF) | ((in).o << 16); \
u32 hi = ((in).e >> 16) | ((in).o & 0xFFFF0000); \
u32 r0, r1; \
r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); \
r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); \
r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); \
r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); \
r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); \
r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); \
r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); \
r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); \
out = (u64)hi << 32 | lo; \
} while (0)
void main(){
unsigned char* k;
u32_2 K0;
//输入参数为u8以及u32类型数据
to_bit_interleaving(K0, U64BIG(*(u64*)k));
}
code
//使用u32数据类型,建奇数偶数下标分开。
u32 lo = (u32)(in); \
u32 r0, r1; \
r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); \
r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); \
r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); \
r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); \
result:
代码分解:
0x22222222=00100010001000100010001000100010
r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1);
0x0C0C0C0C=00001100000011000000110000001100
r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2);
0x00F000F0=00000000111100000000000011110000
r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4);
0x0000FF00=00000000000000001111111100000000
r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8);