首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用位移位运算符进行基转换

使用位移位运算符进行基转换
EN

Stack Overflow用户
提问于 2014-01-02 13:34:47
回答 2查看 4.8K关注 0票数 5

我试图在C中将一些数据从十六进制转换为base64,我在网上找到了一个算法,但我真的很想知道它是如何工作的,而不是仅仅实现它并启动它。如果有人能解释一下下面的工作原理,我将不胜感激。我一直在读关于换挡操作员的文章,但我似乎不像我想的那样理解他们……对我来说,这并不是很简单。

代码语言:javascript
复制
for (x = 0; x < dataLength; x += 3) 
{
  /* these three 8-bit (ASCII) characters become one 24-bit number */
  n = data[x] << 16;

  if((x+1) < dataLength)
     n += data[x+1] << 8;

  if((x+2) < dataLength)
     n += data[x+2];

  /* this 24-bit number gets separated into four 6-bit numbers */
  n0 = (uint8_t)(n >> 18) & 63;
  n1 = (uint8_t)(n >> 12) & 63;
  n2 = (uint8_t)(n >> 6) & 63;
  n3 = (uint8_t)n & 63;

这段代码来自维基百科,它不是我的,我只是想了解一下比特转换,以及它是如何允许我转换数据的。

谢谢你的帮助,我真的很感激。

来源:Base64

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-02 13:52:56

首先,输入数据不是如您所说的十六进制。它只是以字节形式存储的数据。代码将给出它的base64表示(尽管您发布的代码缺少将n0n1n2n3映射到可打印的ASCII字符的部分)。

假设输入的前三个字节是(在二进制表示中,每个字母表示0或1):

代码语言:javascript
复制
abcdefgh, ijklmnop, qrstuvwx

代码的第一部分将它们组合成一个24位数字。这是通过向左移动前一个16位和向左移动第二个8位来完成的,并添加:

代码语言:javascript
复制
  abcdefgh0000000000000000      (abcdefgh << 16)
+ 00000000ijklmnop00000000      (ijklmnop << 8)
  0000000000000000qrstuvwx
  ------------------------
  abcdefghijklmnopqrstuvwx

然后,它通过移动和‘’ing‘将它分成四个6位数。例如,第二个数字是通过向右移动12位和用111111进行‘’ing‘计算的。

代码语言:javascript
复制
n     =   abcdefghijklmnopqrstuvwx

n>>12 =   000000000000abcdefghijkl
63    =   000000000000000000111111

And'ing gives:
          000000000000000000ghijkl
票数 5
EN

Stack Overflow用户

发布于 2014-01-02 14:06:12

好的,这里有一点解释..。

datax是一个字符数组,char通常是8位。(随机8位数01010101) n是一个32位数,这里是一个随机32位数(010111110000111100001110000111111)认为有32位:)

记住n是32位,数据只有8位。让我们通过第一行

代码语言:javascript
复制
 n = data[x] << 16;

<<16优先于等号,因此它首先计算。

datax << 16意味着将数据集所代表的内存中的位向左移动。假设datax = 'a‘用内存中的01100001表示(1个字节),那么让我们向左移动16位

代码语言:javascript
复制
n = 00000000 01100001 00000000 00000000

接下来我们有

代码语言:javascript
复制
if((x+1) < dataLength)
 n += data[x+1] << 8;

这意味着移动下一个字符datax+1 8位,并将其添加到n;因此,让我们首先移动它8位。

代码语言:javascript
复制
( I assumed it was 'a' again)
00000000 00000000 01100001 00000000 
(this is done in some register in your processor)

现在让我们将它添加到n中。

代码语言:javascript
复制
00000000 01100001 01100001 00000000

下一部分是

代码语言:javascript
复制
 if((x+2) < dataLength)
 n += data[x+2];

让我们在这里做同样的事情,注意没有位移动,因为最后的8位n是免费的!我们所需要做的就是将它添加到n中。

B= 01100010 (假定datax+2 = 'b')将其添加到n中

代码语言:javascript
复制
  00000000 01100001 01100001 01100010

很好,现在我们有一个24位数(实际上n是32位,但最后的24位是我们所需要的)。

下半部分

代码语言:javascript
复制
n0 = (uint8_t)(n >> 18) & 63; 
(take note n0 is only 8bits wide or a single unsigned byte)

take n and move it to the left by 18bits and "and" it with 63

n = 00000000 01100001 01100001 01100010
n moved 18bits to right is  00000000 00000000 00000000 00011000

now n is cast to an unsigned int of 8bits (uint8_t)

so now it becomes 00011000

last part is the & operator(bitwise and) 

    00011000 & 
    00111111
n0= 00011000 

现在为剩下的重复这一段

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20884181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档