盗賊の極意

Feed Rss

/* 

一个混淆数字userid的简单方法

效果是 encode: 1234 => 48915174

decode : 48915174 => 1234

*/ 

function encodeNumber( $number, $modulo, $prime ){
    return ( $number * $prime ) & $modulo; // &操作等价于取模
}

function decodeNumber( $code, $modulo, $primeInverse ){
    return ( $code * $primeInverse ) & $modulo; // &操作等价于取模
}

// 例:
// magic number 可以用在线工具事先算出来 http://planetcalc.com/3311/
$modulo = pow( 2, 26 ) - 1;
$prime = 7381371;
$primeInverse = 5555;

$id = 1234;
function show( $number ){
    global $modulo, $prime, $primeInverse;
    $encoded = encodeNumber( $number, $modulo, $prime );
    $decoded = decodeNumber( $encoded, $modulo, $primeInverse );
    print_r( [ 
        "id" => $number, 
        "encoded" => $encoded,
        "decoded" => $decoded,
    ] );
}
show( $id );

----------------  代码文字分隔线  ----------------

有兴趣可以在 http://www.compileonline.com/execute_php_online.php 上演练一下,复制粘贴就好。

简单介绍一下。

出处是这里,我是从stackoverflow上看来的。原理是利用模逆元素的特性,blablabla。
模用2的幂减1是为了求模计算的效率。

限制是可以混淆的数字不能大于模,否则编码后的数值会有重复,或者说会从头开始新一轮循环。
另外这毕竟不是加密,用途类似base64吧,不过不会像base64那样一眼被人识破然后被轻易解读。

密码保护:做一个有偏见的人

06.11.2014, 要查看留言请输入您的密码。, 未分类, by , 981 views.

这是一篇受密码保护的文章。您需要提供访问密码:

手游outgame部分的php工作真的是无脑体力活,纯粹的把企划书翻译成sql代码而已,学不到东西又得不到闲。

这种东西写10年也没有什么积累,高中生教育一下再写3个月一样能代替你。

目前这种东西我已经写了半年了,下一个项目貌似还要让我干这个= =

这还不认真准备跳槽就是对自己不负责了啊,
功能先放一放,专心提高卡牌demo的美工部分,做到可以见人了就去找工作吧!

上海,我来了!

04.07.2014, 11 条评论, 未分类, by , 4,724 views.

五一回家,机票多少钱也要回!

用cocos2d-html5重现一个示例的时候,总是出现各种诡异的显示bug。一开始不够重视,只是让自己的代码越来越接近原本的示例代码,但眼看我整个复制粘贴都不能重现,我就急了。
示例是cocos2d自己的大sample,有一部分framework的,我不能全复制,所以我开始还是怀疑框架中某部分我没有做到。但是朝这个思路走怎么也走不通,甚至一点点苗头都没有,我折磨得肚子都疼了。
真的,因为心急而导致如此明显的生理反应,这已经是多少年不见了……搞不好是第一次遇到这种情况(汗)。
好,你不仁,莫怪我不义。于是开始逐行深入地跟踪,对照着同时单步调试可以正确运行的示例和我的程序。
突然!我发现在让程序停在某个断点处再重新执行的话,断点后面的部分就可以正常显示了!我靠,还有这种bug?我最先想到的是多线程bug,但是在想不通这框架哪里需要用到多线程呢。一边琢磨,一边拿到firefox下试了试,同样是断点后的程序执行正常,排除了跨平台bug的可能。有这个线索就好办了,我一行一行移动这个断点,找到一个关键行“default_item.setSize(default_button.getSize());”。调试时发现getSize值正确,把断点下在下一行,set的结果为0。这样看来是setSize比较可疑吧。一看,setSize果然不是单纯的赋值操作,里面根据几个flag,行为会完全改变的!其中有一个根据this._running来改变行为的逻辑,我想了想,是不是多线程,让这个_runnding时false时true,所以我得到的结果时好时坏呢?朝着这个方向又调试了半天,无果。至此,我调试中作出的每一个预测都落空了。我终于对自己失去了信心,开始无脑单步调试。最后发现getSize的返回值是0(刚才为什么不是0!欺骗我的感情!)。再进一步,是图片取到的size是(0,0)。到这里,我总算是正确理解到问题的原因了。回头想想,确实,helloworld那种只有三张图片的程序里都有一个resource.js文件,还正儿八经的预读了一下,看来预读是很有必要啊。再细追踪了几步,确实是取的图没有在cache里,从这里开始和示例程序的执行流程不同了。这就可以了,不跟踪了,三两下填上预读列表,再试,成功。
其实我之前所在的C++3D射击游戏项目组一直是异步读取图片的(我估计大型游戏都需要异步读取资源)。明明有轮询资源读好了没读好了没的模式的编程经验,自己遇到时却完全没有想到这个原因。反省了一下,应该是我平时自己写程序规模都太小,全是同步读取资源,这么多年思维定势严重了。得赶紧找个大项目参与一下,换换脑子了。

最近写代码的积极性非常差,想想去年白天读代码,晚上学D3D9的旺盛斗志,深感惭愧。

于是今天买早饭时顺便买了速溶咖啡和咖啡用牛奶,准备尝试一下传说中的程序员的觉醒剂了。

咖啡这东西,高中时代为了晚上不困,整包倒嘴里当药吃过几次,无奈当时作息是雷打不动的10点45睡4点55醒,咖啡也没能改变什么。而且现在看来,当时根本是黄金作息,我为什么要尝试晚睡呢,莫名其妙。
印象最深的一次咖啡生效是硕士论文截稿前冲刺的时候,靠同学的一桶咖啡,连写了31小时论文,又因为后劲,最后达成40小时不眠的个人记录。当时真的是感觉到自己进入了一个神器的状态,虚弱,但不困不累,平时活跃得烦人的各种突发奇想都平静了,脑中只处理主业相关任务,有点像考试时的高度集中状态。当然,那肯定也和事关毕业与否的外部条件相关...
总之这次是重新开始挑战咖啡了,希望它带我回到疯狗一般的麻木开发状态。

有人看到我的名字在那个项目组的程序员名单里了,哈哈~

现在这个项目做完,学了php、sql,还有运营时要考虑的一些东西。基本上编程技术没什么提高,但也算是开阔了一下眼界,知道服务器端的事了。如果4月真的能去用Unity做游戏的话,因为还是要用这次的这个网络库,所以我非常有可能继续负责服务器部分。又能动Unity部分,又能做服务器端,不要太开心啊,哈哈哈哈哈!

 

之前为了写node.js的服务器端,根据回调式的编程风格,设计了一种OperationNode(简称Op,而不是On,防歧义)概念,然后用它写了很多代码。不过后来我的服务器端就越写越慢,越来越没有干劲,明明目标很清楚,实现也完全不难,但就是不想动手。怎么办呢,我停下来仔细品味了一下当时的心情,好象是因为代码写不优雅,自己不甘心,觉得写起来没劲,或者是隐约感觉到自己在一条错误的道路上行走,本能的不愿意快走。

那好,”怎么写你(我)才会开心嘛,你写个样子出来看看呗“。这是我设计代码的时候经常用到的一种战术,就是先写一些(有时是很多甚至全部)上层代码,感觉这么写舒服了,再去想怎么实现底层,才能让刚才写的代码生效。我看了看我的卡牌游戏里经常出现的询问玩家是否怎样怎样的AskYesNoOp,至今为止的语法是这样的:

// 询问意向,时限10秒,超时等于选否

this.game.pushOp( new AskYesNoOp( opts, "是否发动场地效果?", 10 ), function( error, result ){

    if ( result ){

        /* ... */

    }else{

        /* ... */

    }

} );

选是的话,后面还要套很多层逻辑,而且每层逻辑都要新写一个Op类,挺痛苦的。理想的写法显然是

var result = asyncAskYesNo( opts, "...", 10 ) ;

switch ( result ){

case ASK_YES_NO_RESULT_YES:

    break;

case ASK_YES_NO_RESULT_NO:

case ASK_YES_NO_RESULT_TIMEOUT:

    break;

}

所以我需要异步功能同步写法。

这种写法我以前常常写的,在lua里,这个叫coroutine,协程。

稍微搜了一下,node.js里就有Fibers库来实现协程功能嘛,安装也很简单,功能也和lua的一样。好,接下来就是逐步割爱换下我的Op,再设计一套coroutine的包装了。估计最后是Op管理大的逻辑,coroutine负责随处可见的琐碎异步。

以前我是听说C++语言里没有协程,所以还挺开心自己掌握了一个少数人可用的秘技,后来搜了一下服务器部分的coroutine,似乎也是有一些的。嗯,又一个扑空了的蓝海,唉。

 

我费了好大功夫,组织了一个特别漂亮的语法,来解决“有则更新,无则插入”的SQL语句,结果不能完全满足需求,现在不得不分拆成: 1)select取所有当前值 2) 分析当前值和新值,该插入插入,该更新更新。非常的朴素。
好吧,我知道这部分浪费掉的时间是错在我的自我满足上,工作还是应该以效率为第一优先,自我学习提升次之。

p.s.: 那个漂亮的MySQL专用语法是 INSERT INTO table_name (`col_01`, `col_02`) VALUES( 1, 1 ), ( 2, 2 ) ON DUPLICATE KEY UPDATE `col_01`=VALUES(`col_01`), `col_02`=VALUES(`col_02`)
后来判断重复还需要参照其他表了(字符串用的都是key,实际值在另一个表里查找),我看太复杂了,还是把工作还给php吧

编程遇到问题的时候,为了解决问题而查东西和尝试性编程时,是可以进入和打lol时一样的亢奋状态的,有这种状态时可以通宵。
另外就是UML已经设计完成,只剩编码时,可以连续长时间内写出大量代码,而且编写时可以分神,听音乐看电视剧什么的,都不太影响编写。这种状态和素描画好型以后上调子时的状态很像,属于体力劳动。

不过我现在是在公司,打开UML工具太明目张胆,直接写呢,就感觉进展比较慢,一边要设计一边要实现,设计受限于已经写好的代码,不好大改,实现也因为设计的小改动而不得不反复跟着改接口。

总之就是很泥泞,粘滞,导致心情不好。

为了缓解烦躁的心情,听了一天きゃりーぱみゅぱみゅ的歌,结果更影响思考了。设计程序时果然只能听纯音乐啊。

听音乐的时候我注意到きゃりー的歌好像词曲总是同一个人——田中やすたか。查了一下,直接震惊了!这人是きゃりー所有作品的词曲作者,同时也是Perfume所有作品的作者,还给一大堆人写过歌,自己还有自己的音乐作品,这……

除了佩服他的造神能力,我更在意的是他这种不正常的产量。作为创作者,高产是美德,也是长期活跃的必要保证。我每天一两百行的低产问题,需要解决一下了。是不是每次都挑战未知领域,所以进展缓慢又耗费热情?我确实不屑重复自己已经习得的技能,不过这里好像还不太一样。应该是,没有清晰明确的目标,一直随手写,大部分时间在关注接口优雅和可重构的地方,所以进度一直是停的。为什么在公司干活,我就能精神亢奋地直奔主题呢。笃志也说过在公司是和策划讨价还价,定下来以后就不想着改策划,一门心思直奔实现去了,自己写则会在意设计细节,在反复重构和推倒重新设计中浪费时间。所以我很想要一个人专门帮我写策划啊!但是我还在服务器端的框架设计阶段,这种技术向的东西没法让人给我写策划啊它又不是界面UI!

那也需要一个固定的目标,这个目标定好了就不能动了。之后以达成这个目标为里程碑开发。不管合不合理,只要实现了里程碑,就可以了。我需要清晰的目标。确实,以前也有过“关掉电脑的时候写程序最快”的感觉,因为那时候可以做纯设计,一旦设计可以定案,之后的实现就只是体力和时间的问题了(干活时可以走神呢~)。今天代码就写到这里,拿起纸笔设计目标吧~