as3 Base85


Base85 与 Base64 相似,为一种把2进制的数据转换为文字数据的编码方式。它将4个2进制字节转换为5个字符,数据的增加率为25%。(Base64为33%)

Base85是在RFC-1924里面定义的。详细请参照RFC-1924
编码方式:
开始
从输入流读4个字节,把值放入uint类型的变量a中。
把a转换为85进制(除以85,求余数)的字符串,并写入输出流。
当输入流的剩余少于4个字节时
从输入流读入剩余的字节,把值放入uint类型的变量a中。
go to 3 (为了效率,这一步应该分为3种情况来写。)
结束
源码:
Base85CharSet.as
/////////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2007 Advanced Flex Project http://code.google.com/p/advancedflex/.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package advancedflex.io.format {
 /**
  * Base85的字符集(Character Set)
  *
  * @see http://rfc.net/rfc1924.html RFC-1924
  * @see Base85Decoder
  * @see Base85Encoder
  */
 public final class Base85CharSet {

  /**
   * 在<strong>RFC-1924</strong>里定义的一般的字符集(根据编码算字符)
   */
   //0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~
  public static const RFC_1924:Array =
  [
   "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
   "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
   "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
   "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d",
   "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
   "o", "p", "q", "r", "s", "t", "u", "v", "w", "x",
   "y", "z", "!", "#", "$", "%", "&", "(", ")", "*",
   "+", "-", ";", "<", "=", ">", "?", "@", "^", "_",
   "`", "{", "|", "}", "~",
  ];
  /**
   * 在<strong>RFC-1924</strong>里定义的一般的逆字符集(根据字符算编码)
   */
  public static const DECODE_RFC_1924:Object =
  {
   "0":0,  "1":1,  "2":2,  "3":3,  "4":4,  "5":5,  "6":6,  "7":7,  "8":8, "9":9,
   "A":10, "B":11, "C":12, "D":13, "E":14, "F":15, "G":16, "H":17, "I":18, "J":19,
   "K":20, "L":21, "M":22, "N":23, "O":24, "P":25, "Q":26, "R":27, "S":28, "T":29,
   "U":30, "V":31, "W":32, "X":33, "Y":34, "Z":35, "a":36, "b":37, "c":38, "d":39,
   "e":40, "f":41, "g":42, "h":43, "i":44, "j":45, "k":46, "l":47, "m":48, "n":49,
   "o":50, "p":51, "q":52, "r":53, "s":54, "t":55, "u":56, "v":57, "w":58, "x":59,
   "y":60, "z":61, "!":62, "#":63, "$":64, "%":65, "&":66, "(":67, ")":68, "*":69,
   "+":70, "-":71, ";":72, "<":73, "=":74, ">":75, "?":76, "@":77, "^":78, "_":79,
   "`":80, "{":81, "|":82, "}":83, "~":84
  };
  /**
   * 在<strong>ascii85</strong>里定义的一般的字符集(根据编码算字符)
   */
   //!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuv
  public static const ASCII85:Array =
  [
   "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*",
   "+", ",",  "-", ".", "/", "0", "1", "2", "3", "4",
   "5", "6",  "7", "8", "9", ":", ";", "<", "=", ">",
   "?", "@",  "A", "B", "C", "D", "E", "F", "G", "H",
   "I", "J",  "K", "L", "M", "N", "O", "P", "Q", "R",
   "S", "T",  "U", "V", "W", "X", "Y", "Z", "[", "]",
   "^", "_",  "`", "a", "b", "c", "d", "e", "f", "g",
   "h", "i",  "j", "k", "l", "m", "n", "o", "p", "q",
   "r", "s",  "t", "u", "v",
  ];
  /**
   * 在<strong>ascii85</strong>里定义的一般的字符集(根据编码算字符)
   */
  public static const DECODE_ASCII85:Object =
  {
   "!":0,  "\"":1, "#":2,  "$":3,  "%":4,  "&":5,  "'":6,  "(":7,  ")":8,  "*":9,
   "+":10, ",":11, "-":12, ".":13, "/":14, "0":15, "1":16, "2":17, "3":18, "4":19,
   "5":20, "6":21, "7":22, "8":23, "9":24, ":":25, ";":26, "<":27, "=":28, ">":29,
   "?":30, "@":31, "A":32, "B":33, "C":34, "D":35, "E":36, "F":37, "G":38, "H":39,
   "I":40, "J":41, "K":42, "L":43, "M":44, "N":45, "O":46, "P":47, "Q":48, "R":49,
   "S":50, "T":51, "U":52, "V":53, "W":54, "X":55, "Y":56, "Z":57, "[":58, "]":59,
   "^":60, "_":61, "`":62, "a":63, "b":64, "c":65, "d":66, "e":67, "f":68, "g":69,
   "h":70, "i":71, "j":72, "k":73, "l":74, "m":75, "n":76, "o":77, "p":78, "q":79,
   "r":80, "s":81, "t":82, "u":83, "v":84
  }
 }
}Base85Encoder.as
/////////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2007 Advanced Flex Project http://code.google.com/p/advancedflex/.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package advancedflex.io.format {
 import flash.utils.ByteArray;
 import flash.utils.IDataInput;

 /**
  * Base85的编码器
  * <p>他把4个字节的2进制数据转换为5个字节的文本数据。数据的增加度为25%。</p>
  *
  * @see Base85CharSet
  * @see Base85Decoder
  */
 public class Base85Encoder {
  /**
   * 用String来编码
   *
   * @param src 原文
   * @param charSet Base85字符集,默认为 Base85CharSet.RFC_1924
   * @return 密文(原文编码后的数据)
   *
   * @see Base85CharSet#RFC_1924
   */
  public static function encode(src:String, charSet:Array = null):String {
   // Convert string to ByteArray
   var bytes:ByteArray = new ByteArray();
   bytes.writeUTFBytes(src);
   bytes.position = 0;
   return encodeByteArray(bytes, charSet ? charSet : Base85CharSet.RFC_1924);
  }

  /**
   * 用ByteArray来编码
   * @param data 原文的输入流
   * @param charSet Base85字符集,默认为 Base85CharSet.RFC_1924
   * @return 密文(原文编码后的数据)
   *
   * @see Base85CharSet#RFC_1924
   */
  public static function encodeByteArray(data:IDataInput, charSet:Array = null):String {
   charSet = charSet ? charSet : Base85CharSet.RFC_1924;
   // Initialise output
   var output:String = "";      //output
   var srcLength:int = data.bytesAvailable; //length of normal bytes
   var endbytes:int = srcLength % 4;   //length of extra bytes.
   var buf:uint;        //encode buffer

   //set this var to correct value.(normal = all - extra)
   srcLength -= endbytes;

   //encode normal group of bytes
   for(var i:int = 0; i < srcLength; i+=4) {
    buf = data.readUnsignedInt();
    output += charSet[buf % 85];
    buf /= 85;
    output += charSet[buf % 85];
    buf /= 85;
    output += charSet[buf % 85];
    buf /= 85;
    output += charSet[buf % 85];
    buf /= 85;
    output += charSet[buf % 85];
   }

   //encode last group of bytes
   buf = 0;
   for(var j:int = 0; j < endbytes; j++) {
    buf = (buf << 8) | data.readByte();
   }
   switch(endbytes) {
    case 0:  //no extra byte
     break;
    case 3:  //has 3 extra bytes
     output += charSet[buf % 85];
     buf /= 85;
    case 2:  //has 2 extra bytes
     output += charSet[buf % 85];
     buf /= 85;
    default: //has 1 extra byte
     output += charSet[buf % 85];
     buf /= 85;
     output += charSet[buf % 85];
   }
   return output;
  }
 }
}Base85Decoder.as
/////////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2007 Advanced Flex Project http://code.google.com/p/advancedflex/.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package advancedflex.io.format {

 import flash.utils.ByteArray;
 import flash.utils.Endian;
 import flash.utils.IDataOutput;

 /**
  * Base85的解码器
  * <p>他把5个字节的文本数据4转换为个字节的2进制数据。</p>
  * @see Base85CharSet
  * @see Base85Encoder
  */
 public class Base85Decoder {

  /**
   * 解码为String
   *
   * @param src 密文
   * @param charSet 逆字符集
   * @return 原文
   *
   * @see Base85CharSet#RFC_1924
   * @see Base85Encoder#encode
   */
  public static function decode(src:String, charSet:Object = null):String {
   var bytes:ByteArray = new ByteArray();
   bytes.writeUTFBytes(src);
   var mark:int = bytes.length;
   decodeByteArray(src, bytes, charSet ? charSet : Base85CharSet.RFC_1924);
   bytes.position = mark;
   return bytes.readUTFBytes(bytes.bytesAvailable);
  }

  /**
   * 解码为ByteArray
   *
   * @param data 密文
   * @param output 输出流
   * @param decharSet 逆字符集
   *
   * @see Base85CharSet#RFC_1924
   * @see Base85Encoder#encodeByteArray
   */
  public static function decodeByteArray(data:String, output:IDataOutput,
     decharSet:Object = null):void {
   decharSet = decharSet ? decharSet : Base85CharSet.DECODE_RFC_1924;
   var dataLength:int = data.length;
   var endbytes:int = dataLength % 5;
   dataLength -= endbytes;
   //decode normal group of bytes
   for(var i:int = 0; i< dataLength;i++) {
    output.writeUnsignedInt(
     decharSet[data.charAt(i)] +
     decharSet[data.charAt(++i)]*85 +
     decharSet[data.charAt(++i)]*(85*85) +
     decharSet[data.charAt(++i)]*(85*85*85) +
     decharSet[data.charAt(++i)]*(85*85*85*85)
    );
   }
   //decode last group of bytes
   var buf:int;
   switch(endbytes) {
    case 0:
     break;
    case 4:
     buf =
     (
      decharSet[data.charAt(i)] +
      decharSet[data.charAt(++i)]*85 +
      decharSet[data.charAt(++i)]*(85*85) +
      decharSet[data.charAt(++i)]*(85*85*85)
     );
     if(output.endian == Endian.BIG_ENDIAN) {
      output.writeByte(
       (buf&0xFF0000) >> 16
      );
      output.writeByte(
       (buf&0x00FF00) >> 8
      );
      output.writeByte(
       (buf&0x0000FF)
      );
     } else {
      output.writeByte(
       (buf&0x0000FF)
      );
      output.writeByte(
       (buf&0x00FF00) >> 8
      );
      output.writeByte(
       (buf&0xFF0000) >> 16
      );
     }
     break;
    case 3:
     output.writeShort(
      (
       decharSet[data.charAt(i)] +
       decharSet[data.charAt(++i)]*85 +
       decharSet[data.charAt(++i)]*(85*85)
      )
     );
     break;
    default: //2
     /* buf =
     (
      decharSet[data.charAt(i)] +
      decharSet[data.charAt(++i)]*85
     ); */
     output.writeByte(
      decharSet[data.charAt(i)] +
      decharSet[data.charAt(++i)]*85
     );
     break;
   }
  }
 }
}
本文来源于 冰山上的播客 http://xinsync.xju.edu.cn , 原文地址:http://xinsync.xju.edu.cn/index.php/archives/183

原文地址:https://www.cnblogs.com/appleseed/p/1292270.html