按位逻辑运算 012345678->02461357


按位逻辑运算:


  • 按位与运算符(&)
    运算规则:只有两个数的二进制同时为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); 

在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值