-
swf 加密:采用byteArray 方式,增加字符串加密,可加密大文件swf
什么都不说:先把工具传上来先。
解密的fla:http://91face.com/swf/loader.fla
使用方法:1.把cba.swf用“abcdef”密文加密,生成abc.swf。2.打开loader.fla(与加密后的abc.swf目录一致),就可以解密,并看到正常的swf文件了。
今天需要用到swf加密,其实我个人来说不是很喜欢加密,flash的精彩源于社区高手的贡献,很多珍贵的代码都可以免费使用,我现做的项目有很多是采用第三方的类库。今天既然项目需要加密的话就加吧,于是试用了好几种现在流行的加密方法:
第一种是使用”swf encrypt”、或者doSWF软件加密,个人认为swf encrypt 的加密不太好,原因不是它算法不够强或者什么的,而是闪客精灵等破解软件会专门针对它的加密算法进行破解。这会导致您加密不久的swf又遭人破了,doSwf是国人写的,还真不错,我试了下加密得很好,连movieClip都看不到。还真想了解下doSwf的加密原理(^.^),现在doSwf是要收费的一年200元,其实钱不是问题(不是我吹牛,至少对于公司来说是这样),钱能解决的问题都不是问题。但是…..(来了:)! ,dowSwf加密大文件的swf有问题,我用我们公司的游戏项目,一个1M左右的swf,加密会出错。所以这种方法对于现有的项目不可行。
第二种方法是采用byteArray二进制加密,此种方法不会使swf变大,只是在原有的字节流中做混淆,对闪客精灵等软件可以起到很好的防破解作用。网上又有源码可以很好地做研究。网址:http://bbs.blueidea.com/thread-2900310-1-97.html 。但是此方法有一个弊端,就是需要一个解密的swf(下面会说到),解密中的密文还是会暴露。衡量了两种方法后准备用第二种,因为简单又可以达到效果。使用后觉得写此加密方法的作者应该是在flash player9是写的,采用的还是用php来生成加密后的swf文件,这样使用起来非常的不便,因为还要布置php的运行环境。因为flash10的:FileReference类可以本地获取与保存二进制数据了。所以决定对其进行改进。
说得此,我先分析下byteArray的加密原理:
byteArray的加密原理是,先用:URLLoader把swf文件加载进来,得到URLLoader的data属性(byteArray类型),然后把这个byteArray数组进行分解,得到一个8位的字节流。然后对这个字节流进行位移(也就是加密的数字,文章中用的是+13),最后得到一个新的字节流数组,进行保存。解密的方法也是如此:先把文件导入进来,得到byteArray,分解成8位的字节流,(解密方法就是对字节流进行反位移,也就是加密是+13,解密就是-13),这样生成新的字节流数组就是可以使用的swf文件了。说到此我不得不佩服原文作者对byteArray机制的理解,不知是否是自己对加密了解甚少,我就是觉得能这样加密就是强(o_o)!(肯定有人笑我了,哈哈)。
这样加密也暴露了只能采用数字加密的问题,后来我又发现一个比较大的问题,就是:加密最核心的原理是对字节流(8位)的加密,因为是8位的,范围只能是:0~255之间,那么你采用超过255的数字加密也是会取余成255的,不信你用256这个数字加密看看,得到的是什么?竟然是加密后的swf,和原来的swf是一致的,原因就是256会变成0,你位移+0,那当然是等于没有变啦。因为这种加密方式生成的加密文件只能有256种,那么我麻烦点在0~255间一个个地试就能得到解密的swf。
为此我改进了加密算法,使用字符串作为密文。把字符串转为一个ASCII数组(如”abc”,对应的ASCII数组为97,98,99),然后与文件的字节流数组进行循环加密。如一个1K的swf,那么它有1024个字节流,第一个字节流与97进行位移,第二个与98位移,第三个与99,第四个又循环与97加。这样生成的加密文件就无穷多了。解密的方法也只有拿到密文才能进行解密。
下面公布加解密方法:
//加密函数
private function compress(byte:ByteArray):ByteArray{
var key:String = password.text; //得到密文var flag:int = 0;
var newByte:ByteArray = new ByteArray();
/* */
for(var i:int = 0; i<byte.length ; i++ ,flag++){
if(flag >= key.length){
flag = 0;
}
newByte.writeByte(byte[i] + key.charCodeAt(flag));
//newByte.writeByte(byte[i] + 256);
}
//输出
fileByteArray = newByte;
saveBtn.visible = true;
return newByte;
}//解密函数
private function uncompress(byte:ByteArray):ByteArray{
var key:String = password.text; //得到密文
var flag:int = 0;var newByte:ByteArray = new ByteArray();
/* */
for(var i:int = 0; i<byte.length ; i++ ,flag++){
if(flag >= key.length){
flag = 0;
}
newByte.writeByte(byte[i] – key.charCodeAt(flag));
//newByte.writeByte(byte[i] + 256);
}
//trace(newByte);
fileByteArray = newByte;
saveBtn.visible = true;
return newByte;
}源文件(flex):http://www.91face.com/swf/entryptSwf.mxml
最后问题是解密的swf,还是会暴露代码。如a.swf把encrypt.swf加载进来后,虽然这个encrypt.swf看不到了,但a.swf还是未加密的,好在此时a.swf会比较小,可以用doSwf加密。doSwf未授权版本也可以绕过,删除其水印与删除其定时弹出的链接。为尊重作者劳动成果,故不公布代码。大家还是去doSwf的网站上购买吧,真希望有一天doSwf也能公布其加密方法,到那时swf加密又会上一个新的台阶了!
最后说句,本人因为平时极少写博客,文字组织能力太差,错别字太多。(555)晚了,回家吧!!!
-
flash生成swc和flex相互问题.
今天一朋友问我flash生成的UI怎么放到flex里,我告诉他生成SWC.一个小时后他说生成了SWC,但是在flex看不到.通过远程操作终于把他遇到的问题解决了.现在说下遇到的几点误区.
在生成SWC前,先看下一个类(UIComponent),flash和flex都能使用这个UIComponent,但flex里是不能用MovieClip类的,这是最容易产生误区的地方.
UIComponent类的继承关系:
flex中的架构,(举例UIComponent类的继承关系)
UIComponent > FlexSprite> Sprite >DisplayObjectContainer>InteractiveObject >Displayobject
flash中的架构(Sprite类的继承关系)
Sprite >DisplayObjectContainer>InteractiveObject >Displayobject所以可以看得出,movieclip并不在继承关系里.那么生成SWC时基类就不能写:flash.display.MovieClip,而是mx.flash.UIMovieClip.
1.我们先打开flash CS3,版本需要profressional.才能生成SWC,还有下载一个小插件flexcomponentkit,这里不多说明.
2.生成一个mc,然后在库面板里右键->属性.如图:

这里要注意,选择”为ActionScript导出”,时默认的基类是flash.display.MovClip,这里需要改为mx.flash.UIMovieClip,否则在flex中使用是看不见此MC的
3.选择此MC,然后选择命令->convert symbol to flex component,再在库面板中选择MC,点击右键,如果是profressional,会出现一个导出SWC文件,点击后保存一个名字,如MC.swc

4.打开flex,选择一个建立好的flex项目.打开项目属性面板->flex build path->Library path,然后点击 Add SWC,选择刚才生成的MC.swc,点击确定

5.如果一切正常,在application中输入<local:就是出现刚才Circle5的类.完整代码local<local:Circle buttonMode=”true”/>运行,OK

-
3D角色选择
3D角色选择
-
新做的initial2 的后台管理页面
新做的initial2 的后台管理页面,
准备用flex+php做此系统,先做一个界面风格给客户,
因为想到客户是一家产品设计公司,于是加重了底色。
-
用AS做一个鼠标跟随的信息提示框
如上例子所示,有很多实现的方法,以前我也在场景中画好一个黑色的背景然后在上面加文字来实现,现在自己想用纯AS来写。
流程是用AS写好一个类实现画背景图、文字、鼠标跟随、隐藏的方法,然后在其他地方写事件触发它。请看tips.as代码:
package {
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFormat;public class tips extends MovieClip {
private var tx:Number = 0;
private var ty:Number = 0;
private var myText:TextField = new TextField();
private var box:Sprite = new Sprite();
public function tips() {
//trace(”构造”);
init();
out();
}
//不显示
public function out():void {
this.visible = false;
}
//显示
public function show():void {
this.visible = true;
}
private function init():void {
//this.alpha = 0.8;
drawBox(200,50);
addChild(myText);
myText.x = 5;
myText.y = 5;
myText.wordWrap = true;
myText.textColor = 0xffffff;
addEventListener(Event.ENTER_FRAME , onFrameHand);
}
public function setWidth(w:int , h:int):void {
box.width = w;
box.height = h;
myText.width = w – 10;
myText.height = h – 10;
}
//画一个文字的底图
private function drawBox(vWidth:int = 100 , vHeight:int = 100) {
box.graphics.beginFill(0×000000,0.8);
box.graphics.lineStyle(1, 0xffffaa,0.8);
box.graphics.drawRect(0,0,vWidth,vHeight);
box.graphics.endFill();
this.addChildAt(box,0);
}
//写text的文字
public function setText(str:String):void {
myText.htmlText = str;
}
private function onFrameHand(e:Event):void {
tx = stage.mouseX+10;
ty = stage.mouseY+10;
//trace(mouseX);
if ((tx + this.width)>stage.stageWidth) {
tx = stage.mouseX – this.width – 10;
}
if ((ty + this.height)>400) {
ty = stage.mouseY – this.height – 10;
}
this. x = tx;
this. y = ty;
}
}
}然后新建一个clew_info.fla ,建立两个元件:hitObj和hitObj2,在帧上写代码:
import tips;
var box:tips = new tips();
addChild(box);hitObj.addEventListener(MouseEvent.MOUSE_OVER , onOverHand);
hitObj.addEventListener(MouseEvent.MOUSE_OUT , onOutHand);
function onOverHand(e:MouseEvent):void{
box.setText(”你好呀,我也是现在才进来<b>玩这个游</b>戏的<br/><br/>你喜欢吗?”);
box.setWidth(150,60);
box.show();
}
function onOutHand(e:MouseEvent):void{
box.out();
}hitObj2.addEventListener(MouseEvent.MOUSE_OVER , onOverHand2);
hitObj2.addEventListener(MouseEvent.MOUSE_OUT , onOutHand2);
function onOverHand2(e:MouseEvent):void{
box.setText(”第二个提示内容\n第二个提示内容消息”);
box.setWidth(100,60);
box.show();
}
function onOutHand2(e:MouseEvent):void{
box.out();
}就OK了。
box.setText(”"); box.setWidth(100,60); box.show(); box.out(); 都是tips这个类写好的方法。通过这样的方法,实现了逻辑与具体实现分开,传统OOP的做法。
下面是源文件:
提示框源文件 -
试做flash游戏中的格子地图
今天做了一个flash格子地图的测试,要求是像游戏“三国志”一样在格子上建筑房子,每个格子是由棱形组成的。所以先建一个棱形的mc,然后用循环输出棱形,最后合成了格子地图。
测试中点击并没有房子,只是简单地输出了文字。下面是swf文件:
总结:做这种地图最难的是算法,研究这算法就花了我几页纸。数学不好还是不行。
源文件下载:map
-
flash 的p2p功能
flash的新协议:RTMFP , 服务允许Flash Player 10和AIR 1.5开发的客户端以P2P的形式交换数据。这里的P2P采用的是UDP协议,这项新的UDP协议被Adobe赋予一个新的名字:RTMFP(real time flow protocol),底层用UDP协议具有稳定、彻底减缓延迟,并且可以大大节省带宽,请看图示。 详细技术要等官方出文档。
-
自己用flash 做的接金币小游戏.
自己用flash 做的接金币小游戏.
键盘的左右键控制小企鹅的方向.还是个半成品,刚才测试了一下,发现还有很多问题.日后改进下.
-
Flex 的RemoteObject 通讯遇到的问题
今天做了一些flex的测试,是根据”flex第一步”这一本书来做的,主要是在服务端写一个java的类读取数据库数据,然后通过FDS用remotion来做通讯.
java服务端是这样写的:
package tree;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Collection;
public class GetUserService {
public static void main(String args[]){
GetUserService db = new GetUserService();
Collection arr = db.getUsers();
System.out.println(arr.toString());
}
//定义函数
public Collection getUsers(){
ArrayList<Map> list = new ArrayList<Map>();
String dbDriver = “com.mysql.jdbc.Driver”;
String dbServer = “localhost”;
String dbName = “walktree”;
String dbUser = “root”;
String dbPass = “feifei”;
String url = “jdbc:mysql://” + dbServer +”/”+dbName+”?user=”+dbUser+”&password=”+dbPass;
try{
Class.forName(dbDriver);
}catch(ClassNotFoundException e){
System.out.println(”连接出错”);
return null;
}
try{
Connection con = DriverManager.getConnection(url);
//创建数据库操作对象
Statement sta = con.createStatement();
String sql = “select * from userinfo”;
ResultSet rs = sta.executeQuery(sql);
Map<String , Object> user;
while(rs.next()){
user = new HashMap<String , Object>();
user.put(”username”, (String)rs.getString(”username”));
user.put(”url”, (String)rs.getString(”url”));
user.put(”email”, (String)rs.getString(”email”));
list.add(user);
//System.out.println(rs.getString(”username”));
}
return list;
}catch(SQLException e){
System.out.println(”无数据”);
return null;
}
}
}然后flex代码:
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” fontSize=”12″
creationComplete=”init()”>
<mx:Script>
<![CDATA[
import mx.rpc.http.HTTPService;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import flash.events.Event;
import mx.managers.CursorManager;internal function init():void{
service.getUsers();
}
internal function resultHand(evt:ResultEvent):void{
CursorManager.removeBusyCursor();
myList.labelField = "username";
myList.dataProvider = evt.result;
}
internal function faultHand(evt:FaultEvent):void{
emailTxt.text = "fault"+evt.fault;
trace("fault"+evt.fault);
}
internal function selectHand(evt:Event):void{
var user:Object = myList.selectedItem;
userPanel.title = "详细信息"+user.username;
userTxt.text = user.username;
emailTxt.text = user.email;
urlTxt.text = user.url;
}
]]>
</mx:Script><mx:RemoteObject id=”service” fault=”faultHand(event)” showBusyCursor=”true”
destination=”userService” >
<mx:method name=”getUsers” result=”resultHand(event)” />
</mx:RemoteObject>
<mx:Panel x=”10″ y=”10″ width=”156″ height=”286″ layout=”absolute” title=”名册”>
<mx:List id=”myList” x=”0″ y=”0″ width=”100%” height=”244″ change=”selectHand(event)”/>
</mx:Panel><mx:Panel x=”183″ y=”10″ width=”276″ height=”286″ layout=”absolute” id=”userPanel”>
<mx:Label x=”10″ y=”10″ text=”Label” id=”userTxt” fontWeight=”bold”/>
<mx:Label x=”12″ y=”38″ text=”Label” id=”emailTxt”/>
<mx:Label x=”12″ y=”66″ text=”Label” id=”urlTxt”/>
</mx:Panel></mx:Application>
最后在tomcat下就是显示不出数据来,于是做了一些测试,在getUsers()函数最后返回一个字符串,如”Hell”,这样在在flex端就可以显示出内容,开始时怎么也想不出问题所在.怀疑是Map的数据与flex的不兼容,于是做了这样一个测试.:
ArrayList<Map> list = new ArrayList<Map>();
Map<String , String> note = new HashMap<String, String>();
note.put(”username”, “king”);
note.put(”email”, “king@163.com”);
note.put(”url”,”http://king.com”);
list.add(note);
Map<String , String> note2 = new HashMap<String, String>();
note2.put(”username”, “小明”);
note2.put(”email”, “xiao@163.com”);
note2.put(”url”,”http://xiao.com”);
list.add(note2);
return list;最后可以通过,flex显示,继续找答案,最后终于找到了.是因为服务端的程序,
Map<String , Object> user;
user = new HashMap<String , Object>();定义了Object,在java中Object类型的数据是如何应用的,我虽然不能说得很明白,但它至少不会像flex中的Object类型一样使用.而这本书明明是这样写的.看来此书《FLEX第一步》的很多代码是未经过测试的。国内的书一般都会多少有这样的特点,不是我极端。
明白了问题所在后,把上面的代码修改成:
Map<String , String> user;
user = new HashMap<String , String>();这样返回的值就显示正常了。





