skip to main |skip to sidebar

2007-09-17

[AS3] Base85 的实现

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

Base85是在RFC-1924里面定义的。详细请参照RFC-1924

编码方式:

  1. 开始
  2. 从输入流读4个字节,把值放入uint类型的变量a中。
  3. 把a转换为85进制(除以85,求余数)的字符串,并写入输出流。
  4. 当输入流的剩余少于4个字节时
    1. 从输入流读入剩余的字节,把值放入uint类型的变量a中。
    2. go to 3 (为了效率,这一步应该分为3种情况来写。)
  5. 结束

源码:

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;
}
}
}
}

asdoc的技巧 - 链接的别名

在asdoc里,使用@see时有时候需要给链接去一个别名。 即http://syncspace.blogspot.com/ 应为 Synchronous Space

其实@see的语法为

@see URL [别名]

别名可以包含任何字符(除了换行符以外)

所以上面的例子应为

@see http://syncspace.blogspot.com/ Synchronous Space

2007-09-09

AS3.0的优化(1)

AS3.0在内部做了一些优化,并引入了JIT,但还是有需要争分夺秒的地方。比如游戏的AI等运算量大的算法。

以下列出一些优化公式:(每个公式均测试5次,取平均值,每次循环次数为6000000,单位为ms)

//当x为int时
-x    => ~x+1 // 从 134 到 8
-x-1  => ~x   // 从 154 到 5
-(~x) => x+1  // 从 130 到 8

在内部,-x有可能被编译为(-1) * x。而~x+1却为inc ~x(inc 为CPU的内部命令,意思是加一)。下面的两个公式就不用解释了。

2007-09-05

Flash Player9的普及率突破90%的大关!

Flash Player9的普及率终于突破90%的大关!

AS3.0终于可以成为主流了!

2007-09-02

本博客的版本声明(Copyright)

本博客的除计算机源代码与特别注明以外均采用

Creative Commons 署名-非商业性使用-相同方式共享 3.0 Unported

CreativeCommonsLicense

的许可协议

您可以自由:

  • 复制、发行、展览、表演、放映、广播或通过信息网络传播本作品
  • 创作演绎作品

惟须遵守下列条件:

  • 署名. 您必须按照作者或者许可人指定的方式对作品进行署名。

  • 非商业性使用. 您不得将本作品用于商业目的。

  • 相同方式共享. 如果您改变、转换本作品或者以本作品为基础进行创作,您只能采用与本协议相同的许可协议发布基于本作品的演绎作品。

详细条款请参看法律文本(许可协议全文)(英文)

对于计算机源代码,除特别注明以外均采用

Apache License Version 2.0

  Copyright 2007 Stephen 

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.

协议。需要满足的条件:

1. 需要给代码的用户一份Apache Licence

2. 如果你修改了代码,需要再被修改的文件中说明。

3. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。

4. 如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。

详细条款请看Apache License, Version 2.0(英文)

博客的模板等关于博客的格式(非文章内容):

(c)Copyright All Rights Reserved.

用Ant来打包(compc)flex的源文件为SWC

直接用compc来打包flex源文件是很复杂且繁琐的事。但用了Ant,在Eclipse里一切都变为按一个键。

compc.xml:

<!--/////////////////////////////////////////////////////////////////////////////
//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.
///////////////////////////////////////////////////////////////////////////// -->
<project name="Compc build" default="main">
<!-- defines all values for the Compc compiler -->
<property file="compc.properties" />
<!-- main target: cleans and compiles ASDocs -->
<target name="main" depends="clean, log, compc" />
<!-- deletes and recreates the compc directory -->
<target name="clean">
<delete dir="${output.dir}" failonerror="true"/>
<mkdir dir="${output.dir}"/>
</target>
<!-- runs the compc.exe compiler on the source -->
<target name="compc">
<exec executable="${compc.exe}" failonerror="true">
<arg line="-include-sources '${src}'" />
<arg line="-output '${output.dir}/${output.file}'" />
</exec>
</target>
<!-- writes compc output to log file: compc-log.log -->
<target name="log">
<record name="${output.dir}/compc-log.log" action="start" append="true" />
</target>
</project>

compc.properties:

################################################################################
##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.
############################################################################### #compc.exe的位置
compc.exe =C:/Program Files/Adobe/Flex Builder 2 Plug-in/Flex SDK 2/bin/compc.exe #源文件的位置
src = #输出的位置
output.dir = #输出的文件名
output.file =