`
kerry001
  • 浏览: 38257 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

把一个字节按位翻转

    博客分类:
  • C
阅读更多
很久没有玩过C语言的位操作了,今天重温了一下,并做了一道之前自己跟同事聊过的一道题,就是把一个字节按位翻转,举例来说,就是有二进制数(10010011),翻转之后就变为(11001001).
这一道题还是挺容易的,相信学过C语言的人都可以解决出来,简单地说,做一个循环就可以了,但如果想要取得更高的效率,就有很多考究了.
我们先不要看一个字节的情况,因为一个字节实在是太长了点…我们来看看只有两个二进制位的情况下,是怎么样的.
假设有二制数a = 01B,翻转后则为10B,同样的,如果原来是10B,翻转后则为01B.我们再试一下,可以发现如果原来为11B或者00B,翻转后则不变.这时我们可以写出两位二进制数的翻转算法如下:
if( a == 01B || a == 10B )
  a ^= 11B;
else
  a = a;
大家知道,给某二进制数的某一位异或(^)一个1,可将其取反,所以上面的a ^= 11B实际将a按位取反了,也即是从01B变为10B,或者从10B变为01B,这样我们可以看到他们实现了翻转.
推而广之,翻转一个字节,其实就是把第0位与第7位互换,把第1位与第6位互换等等.那么,上面的式子是否可以推而广之呢?事实上是可以的.
设有a = 10001100B;
执行a ^= 10000001B;
这时,a的二进制数为00001101B,第0位与第7位互换了!推广下去,a ^= 01000010B则是互换第1位和第6位,a ^= 00100100B是第2和第5位等等…….
那,我们实现了这个问题的解法了吗?没有!因为我们刚才没有考虑到当第0位和第7位相等,第1位和第6位相等等等的情况!在两个对应位相等的情况下,根据上面的翻转算法,我们不应该执行异或运算,因此,我们现在的任务就是分辩出对应位是否相等.
大家有没有什么好方法可以分辨出两个位是否相等?
再回头来看给我们很多启示的只有两个位的二进制数a,假设a = 11B,那么,这个数有什么特点呢?我们发现,( a | 11B ) == a 而当a = 01B,10B,00B的时候都不会出现这样的情况.这样我们就识别出11B的特殊情况,那么,还有一种情况就是a = 00B,它又有什么特别呢?仔细想一想,聪明的读者可能已经发现当a = 00B时, ( a ^ 11B ) == ( a | 11B ),而当a = 01B,10B,11B的时候都不会使这个等式成立,这样我们就可以把00B的特殊情况识别出来了.
进行类似上文的从二位二进制推广到八位二进制的方法,把上面的识别算法也推广到八位后,写程序如下:
#include "stdafx.h"
int main(int argc, char* argv[])
{
 unsigned char a, b, c;
 a = 17;
 if( ( b = a | 0x81 ) != a
  && ( c = a^0x81 ) != b )
  a = c;
       if( ( b = a | 0x42 ) != a
  && ( c = a^0x42 ) != b )
  a = c;
       if( ( b = a | 0x24 ) != 
  && ( c = a^0x24 ) != b )
  a = c;
       if( ( b = a | 0x18 ) != a
  && ( c = a^0x18 ) != b )
  a = c;
 printf("%d\n", a );
 return 0;
}

至此,一个将字节按位翻转的程序就出来了,但是,相信好学的读者是不会满足的,还有什么更好地优化它的算法吗?动动脑筋,当然有!

引自:http://lanphaday.bokee.com/3788582.html
分享到:
评论

相关推荐

    把一个字节按位翻转源代码,C语言编写

    这是因为异或操作具有交换律和结合律,当一个位是1,另一个位是0时,异或结果为1,反之为0。所以,对于01B和10B,异或11B(1的位与0的位对应,0的位与1的位对应),相当于全部位翻转。 当扩展到一个字节(8位)时,...

    易语言字节集翻转

    1. **定义字节集变量**:首先,我们需要创建一个字节集变量来存储我们要翻转的数据。例如,`字节集_原始 = ...`,这里省略了具体的数据初始化部分。 2. **获取字节集长度**:使用`取字节集长度`函数来获取字节集的...

    易语言源码易语言字节集翻转源码.rar

    总之,"易语言源码易语言字节集翻转源码.rar"是一个宝贵的资源,它提供了用易语言处理二进制数据的实例,对于想要深入理解和使用易语言,尤其是涉及二进制操作的开发者来说,这是一个很好的学习材料。通过研究这个...

    基于Qt的整数按位反转实现

    例如,你可以创建一个自定义的输入框控件,当用户输入一个数字后,实时显示其按位反转的结果。 总之,基于Qt的整数按位反转实现结合了Qt的数据转换功能和位运算,提供了一种直观且灵活的方式来处理二进制位反转。...

    CBC字节翻转攻击与padding oracle攻击

    CBC字节翻转攻击与padding oracle攻击 CBC 字节翻转攻击是指在使用 CBC 加密模式时,如果攻击者可以控制明文最后的一部分,并且可以观察到密文的变化,那么攻击者可以通过修改明文的最后一部分来观察密文的变化,...

    BMP格式图片的翻转

    一个BMP文件通常由文件头、信息头和像素数据三部分组成。文件头包含了文件的基本信息,如文件大小、图像偏移量等;信息头则包含图像的宽高、色彩位深等详细信息;而像素数据则是按照行优先的原则存放的,即从上到下...

    高低字节交换SWAP演示.rar

    高低字节交换(Byte Swapping),又称为字节翻转,是一种处理字节顺序的技术,主要用于解决大端字节序和小端字节序之间的转换问题。大端字节序是指数据的最高有效字节存储在最低地址,而小端字节序则相反,最低有效...

    易语言字节集翻转源码-易语言

    在实际代码中,我们可能会先创建一个字节集,然后通过循环或其他方法将字节集的内容读取出来,反向存储到新的字节集中,最后用新的字节集替换原来的字节集,完成翻转操作。这样的程序逻辑可以确保字节集的顺序得到...

    高低字节转换工具

    用于TXT文本文档存储的16进制文件的高低字节的转换以及数据校验

    c++ 编程bmp图像翻转处理

    5. 完成所有行的处理后,将新内存写入一个新的BMP文件,创建一个水平翻转的图像。 对于垂直翻转,处理方式略有不同,需要从下至上读取像素: 1. 同样,打开BMP文件并获取图像信息。 2. 分配内存。 3. 从最后一行...

    verilog实现图像翻转程序

    - 24位BMP文件每个像素由3个字节表示(红绿蓝各占一个字节)。 3. **Verilog实现图像翻转** - 本例中的代码主要分为两个部分:读取图像数据和写入翻转后的图像数据。 - 使用了`$fopen`和`$fclose`等Verilog内置...

    按位异或校验和计算器

    如果一个位是1,另一个位是0,异或结果为1。在按位异或校验和中,我们将所有数据的每一位进行异或操作,最终得到的单一结果就是校验和。 在C#编程语言中,我们可以使用位运算符来实现按位异或校验和。下面是一个...

    十六进制按位解析,BitDecode

    - 对二进制数据进行按位解析,意味着将二进制数分解为单个位(bit),每个位都有其特定的值和意义,特别是在处理具有特定结构的数据时,如计算机指令、网络报文或硬件寄存器状态。 3. **寄存器字段**: - 寄存器...

    MFC4字节地址翻转工具

    比如12345678能变成78563412,如果长度不够,自动补0

    php简单实现多字节字符串翻转的方法

    首先,我们需要了解`mb_strlen()`函数,它是PHP中的一个多字节安全的字符串长度获取函数。它会根据指定的编码识别字符串中的字符数,而不是字节数。例如: ```php $encoding = 'UTF-8'; $string = '你好,世界!'; ...

    VC 对字符进行错切、翻转、倒置、对称处理

    在计算机中,字符通常由ASCII或Unicode编码表示,如ASCII码对应一个字节,Unicode码可能需要两个或更多字节。在屏幕上显示字符,我们需要将这些编码转换为像素,这个过程涉及字体渲染技术。 接下来,我们讨论字符的...

    bmp翻转与缩放

    在"压缩包子文件的文件名称列表"中提到的"BMPZoom"可能是一个示例程序或者包含示例代码的文件,它演示了如何用二进制方式处理BMP文件并实现翻转和缩放。 总之,理解和操作BMP文件涉及到了计算机图形学的基本概念,...

    swap_uchar.zip_swap_位域赋值_位赋值

    例如,我们可能有一个结构体,其中包含几个位字段,每个字段代表不同的功能。位域赋值就是向这些位字段赋值的过程,这有助于我们精确控制内存的低级别操作。 ```c struct BitField { unsigned int bit1 : 1; // ...

    第三C语言讲解位运算PPT课件.pptx

    异或运算常用于判断两个位是否不同,并可以用来翻转一个数值的特定位。例如,如果你想翻转一个数的低4位,可以将它与一个掩码(如00001111)进行异或。 这些位运算符在计算机科学中有着广泛的应用,特别是在处理...

Global site tag (gtag.js) - Google Analytics