在union中使用结构来编码base64

时间:2015-10-14 22:19:53

标签: c++ struct base64 unions

我见过很多关于如何实现Base64编码器的例子。但是它们都没有在联合内部使用struct来完成从三个8位块到四个6位块的转换。而且我想知道为什么没有人使用这种方法,因为对我来说它看起来像一个简单快速的方法。

我在union-struct中写了一个例子。

namespace Base64
{
    typedef union
    {
        struct
        {
            uint32_t b2     : 0x08;
            uint32_t b1     : 0x08;
            uint32_t b0     : 0x08;
            uint32_t pad    : 0x08;
        } decoded;
        struct
        {
            uint32_t b3     : 0x06;
            uint32_t b2     : 0x06;
            uint32_t b1     : 0x06;
            uint32_t b0     : 0x06;
            uint32_t pad    : 0x08;
        } encoded;
        uint32_t raw;
    } base64c_t;
}

我已经测试过使用此方法将0xFC0FC0或二进制111111000000111111000000转换为四个6位块,它似乎有效。

Base64::base64c_t b64;

b64.decoded.b0  = 0xFC;
b64.decoded.b1  = 0x0F;
b64.decoded.b2  = 0xC0;

std::cout.fill ( '0' );

std::cout << "0x" << std::hex << std::setw ( 2 ) << b64.encoded.b0 << std::endl;
std::cout << "0x" << std::hex << std::setw ( 2 ) << b64.encoded.b1 << std::endl;
std::cout << "0x" << std::hex << std::setw ( 2 ) << b64.encoded.b2 << std::endl;
std::cout << "0x" << std::hex << std::setw ( 2 ) << b64.encoded.b3 << std::endl;

输出:

0x3f
0x00
0x3f
0x00

这种将8位块转换为6位块的方法是否存在缺点?或者还没有人提前考虑过这种方式?

1 个答案:

答案 0 :(得分:2)

在结构中打包位域的顺序是实现定义的。因此,虽然您在 计算机上获得了正确的base64结果,但是当您将此代码移植到不同的体系结构或编译器(例如,big-endian PowerPC)时,您可能会得到完全不同的(错误!)答案。借用this answer

  

未指明的行为

     
      
  • 分配用于保存位字段(6.7.2.1)的可寻址存储单元的对齐。
  •   
     

实施定义的行为

     
      
  • 位字段是否可以跨越存储单元边界(6.7.2.1)。
  •   
  • 单位内的位域分配顺序(6.7.2.1)。
  •   

因此,您最好使用位移代码(这基本上是每个base64实现所使用的代码),因为这将保证跨平台的相同。