繁体   English   中英

C ++中Base64编码函数的按位移位

[英]Bitwise shifting for Base64 encode function in C++

我正在尝试用C ++重写此javascript base64编码例程(请注意,它是非标准的base64,并且在解码字符串的开头有一个。)。

这是JS脚本的示例-https: //jsfiddle.net/km53844e/1/

我在下面发布了javascript base64类。

在JS脚本中,它将CcnK正确转换为CMlaKA。 但是,在C ++脚本中,它错误地将其转换为CMlaKr(不知道为什么,这可能与JS脚本中的其他NaN语句有关吗?

还是可能与C ++脚本中以null结尾的字符串有关? 我注意到,如果删除此选项,我会得到仍然不正确的CMlaK。

我尝试添加以下内容来处理isnans,但它不起作用。

  if (isnan(char_array_4[1])) {
            char_array_4[2] = char_array_4[1] = 64;
        } else if (isnan(char_array_4[2])) {
            char_array_4[3] = 64;
        }

C ++代码:

std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
  std::string ret;
  int i = 0;
  int j = 0;
  unsigned char char_array_3[3];
  unsigned char char_array_4[4];

  while (in_len--) {
    char_array_3[i++] = *(bytes_to_encode++);
    if (i == 3) {
      char_array_4[0] = char_array_3[0] & 0x3f;
      char_array_4[1] = ((char_array_3[0] & 0x0f) << 2) + ((char_array_3[1] & 0xc0) >> 6);
      char_array_4[2] = ((char_array_3[1] & 0x03) << 4) + ((char_array_3[2] & 0xf0) >> 4);
      char_array_4[3] = (char_array_3[2] & 0xfc) >> 2;

        if (isnan(char_array_4[1])) {
            char_array_4[2] = char_array_4[1] = 64;
        } else if (isnan(char_array_4[2])) {
            char_array_4[3] = 64;
        }

      for(i = 0; (i < 4) ; i++)
        ret += base64_chars[char_array_4[i]];
      i = 0;
    }
  }

  if (i)
  {
    for(j = i; j < 3; j++)
    char_array_3[j] = '\0';

    char_array_4[0] = char_array_3[0] & 0x3f;
    char_array_4[1] = ((char_array_3[0] & 0x0f) << 2) + ((char_array_3[1] & 0xc0) >> 6);
    char_array_4[2] = ((char_array_3[1] & 0x03) << 4) + ((char_array_3[2] & 0xf0) >> 4);
    char_array_4[3] = (char_array_3[2] & 0xfc) >> 2;

        if (isnan(char_array_4[1])) {
            char_array_4[2] = char_array_4[1] = 64;
        } else if (isnan(char_array_4[2])) {
            char_array_4[3] = 64;
        }

    for (j = 0; (j < i + 1); j++)
      ret += base64_chars[char_array_4[j]];

    while((i++ < 3))
      ret += '=';

  }

  return ret;

}

JS代码:

var Base64 = {
        _keyStr: ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=",

    encode : function (input) {
        var output = [],
            chr1, chr2, chr3, enc1, enc2, enc3, enc4,
            i = 0;
        while (i < input.length) {
            chr1 = input[i++];
            chr2 = input[i++];
            chr3 = input[i++];

            enc1 = chr1 & 0x3f;
            enc2 = (chr1 >> 6) | ((chr2 & 0xf) << 2);
            enc3 = (chr2 >> 4) | ((chr3 & 0x3) << 4);
            enc4 = chr3 >> 2;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output.push([this._keyStr.charAt(enc1),
                         this._keyStr.charAt(enc2),
                         this._keyStr.charAt(enc3),
                         this._keyStr.charAt(enc4)].join(''));
        }

        return output.join('');
    },

    decodeAsArray: function (b) {
        var d = this.decode(b),
            a = [],
            c;
                //alert("decoded base64:" + d);
        for (c = 0; c < d.length; c++) {
            a[c] = d.charCodeAt(c)
        }
                //alert("returning a");
        return a
    },

    decode: function( input ) {
        var output = "";
        var chr1, chr2, chr3 = "";
        var enc1, enc2, enc3, enc4 = "";
        var i = 0;

        do {
            enc1 = this._keyStr.indexOf(input.charAt(i++)) ;
            enc2 = this._keyStr.indexOf(input.charAt(i++)) ;
            enc3 = this._keyStr.indexOf(input.charAt(i++)) ;
            enc4 = this._keyStr.indexOf(input.charAt(i++)) ;

            chr1 = (enc1 | ((enc2 & 3) << 6));
            chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
            chr3 = (enc3 >> 4) | (enc4 << 2);

            output = output + String.fromCharCode(chr1);
            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
                        }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }
            chr1 = chr2 = chr3 = "";
            enc1 = enc2 = enc3 = enc4 = "";
        } while (i < input.length);

        return (output);
    }

};

因此,当您将c ++代码与JavaScript进行比较时,isnan()应该如下所示:

if (isnan(char_array_3[1])) { // char_array_3[1] = chr2
    char_array_4[2] = char_array_4[1] = 64; // char_array_4[2] = enc3 & char_array_4[1] = enc2
} else if (isnan(char_array_3[2])) { // char_array_3[2] = chr3
    char_array_4[3] = 64; // char_array_4[3] = enc2
}

但是主要的问题是isnan()函数仅专用于C ++中的浮点值,并且与JavaScript中的含义不同。

代替使用那个isnan()函数,替换base64_encode()的以下部分:

  while (in_len--) {
    char_array_3[i++] = *(bytes_to_encode++);
    if (i == 3) {
    ...
    if (isnan(char_array_4[1])) {
        char_array_4[2] = char_array_4[1] = 64;
    } else if (isnan(char_array_4[2])) {
        char_array_4[3] = 64;
    }
    ...
    for(i = 0; (i < 4) ; i++)
       ret += base64_chars[char_array_4[i]];
    i = 0;
  }

通过以下之一:

1-为防止在输入缓冲区中剩余少于3个字节时出现意外值,请将其强制为0x00。 同样在每个下一个循环之前( for(j=0;j<3;j++) char_array_3[j]=0x00; )。

2- if (i == 2)从输入缓冲区中加载了2个字节,则输出缓冲区的最后一项设置为64。

3- if (i == 1)仅从输入缓冲区加载了1个字节,则输出缓冲区的最后2个项目将设置为64。

  for(j=0;j<3;j++) char_array_3[j]=0x00; // initialize input array
  while (in_len--) {
    char_array_3[i++] = *(bytes_to_encode++);
    if ((i == 3) || (in_len == 0)) { // encode when 3 bytes or end of buffer
    ...
    if (i == 1) { // instead of (isnan(char_array_4[1]))
        // both char_array_3[1] and char_array_3[2] are not defined
        char_array_4[3] = char_array_4[2] = 64;
    } else if (i == 2) { // instead of (isnan(char_array_4[2]))
        // char_array_3[2] is not defined
        char_array_4[3] = 64;
    }
    ...
    for(i = 0; (i < 4) ; i++)
       ret += base64_chars[char_array_4[i]];
    i = 0;
    for(j=0;j<3;j++) char_array_3[j]=0x00; // initialize input array
  }

与JavaScript相比,C ++中base64_encode()函数的最后一个错误在中间项的输出缓冲区计算中。 代替以下任务:

  char_array_4[0] = char_array_3[0] & 0x3f;
  char_array_4[1] = ((char_array_3[0] & 0x0f) << 2) + ((char_array_3[1] & 0xc0) >> 6); // NOK
  char_array_4[2] = ((char_array_3[1] & 0x03) << 4) + ((char_array_3[2] & 0xf0) >> 4); // NOK
  char_array_4[3] = (char_array_3[2] & 0xfc) >> 2;

使用以下内容:

1-当计算char_array_4[1] (在JS中为enc2 )时,将对char_array_3[0] (在JS中为chr1 )和char_array_3[1] (在JS中的chr2 )进行反转。

2-计算char_array_4[2] (在JS中为enc3 )时,将对char_array_3[1] (在JS中为chr2 )和char_array_3[2] (在JS中的chr3 )进行反转。

  // JS =>  enc1 = chr1 & 0x3f;
  char_array_4[0] = (char_array_3[0] & 0x3f); // OK
  // JS =>  enc2 = (chr1 >> 6) | ((chr2 & 0xf) << 2);
  char_array_4[1] = ((char_array_3[0] & 0xc0) >> 6) + ((char_array_3[1] & 0x0f) << 2); // OK
  // JS => enc3 = (chr2 >> 4) | ((chr3 & 0x3) << 4);
  char_array_4[2] = ((char_array_3[1] & 0xf0) >> 4) + ((char_array_3[2] & 0x03) << 4); // OK
  // JS => enc4 = chr3 >> 2;
  char_array_4[3] = (char_array_3[2] & 0xfc) >> 2;

进行这些更正后, if (i)条件块if (i)无效,则应将其删除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM