2017年3月

网易的一元夺宝和快夺宝作弊的可能

网易的一元夺宝和快夺宝号称是绝对公平,其实还是有一定的操作空间,他的数值A和数值B,数值B是参考时时彩,但是时时彩的每个号码其实是有一定的概率,比喻说时时彩来了1000期,那这1000期的号码再次出现的概率非常非常低,他们在后台,在开奖前给真实用户的号码,很多久是参考这些已经开过的期模拟跑过,大概能控制20%到30%的效果。数值A的毫秒数基本都是机器算的。

a0.jpg

a1.jpg

a2.png

redis达到maxmemory报错

redis在使用过程中,平时运行的都没有问题,突然有一天(error) OOM command not allowed when used memory > max ,redis报错了,看服务器还有内存可用,通过info来看,确实达到了redis设置的最大值,排查程序发现是有一个消费的程序没有启动,造成key越积越多,所以redis是使用过程中,根据业务需要设置过期时间是一个好的习惯,或者修改淘汰规则这个配置也可以。

Nodejs AES/CBC/PKCS5Padding 例子

网上很多对用Nodejs做AES/CBC/PKCS5Padding的时候都是没有padding,在实际使用中,都需要单独设置KEY和IV的。
aes.js

'use strict';
var crypto = require('crypto');
var CBC = 'cbc';
var ECB = 'ecb';
var NULL_IV = new Buffer([]);

var IV = new Buffer([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
var cipherMode = CBC;
var keySize = 128;
var algorithm;
setAlgorithm();
var outputEncoding = 'base64';
var inputEncoding = 'utf8';

function setAlgorithm() {
    algorithm = 'aes-' + keySize + '-' + cipherMode;
}

function setCipherMode(mode) {
    if (mode !== CBC && mode !== ECB) {
        throw ('AES.setCipherMode error: ' + mode);
    }
    cipherMode = mode;
    setAlgorithm();
}

function setKeySize(size) {
    if (size !== 128 && size !== 256) {
        throw ('AES.setKeySize error: ' + size);
    }
    keySize = size;
    setAlgorithm();

}



function checkKey(key) {
    if (!key) {
        throw 'AES.checkKey error: key is null ';
    }
    if (key.length !== (keySize / 8)) {
        throw 'AES.checkKey error: key length is not ' + (keySize / 8) + ': ' + key.length;
    }
}

function encBytes(buff, key, newIv) {
    checkKey(key);
    var iv = newIv || IV;
    var cipher = crypto.createCipheriv(algorithm, key, iv);
    cipher.setAutoPadding(true);
    var re = Buffer.concat([cipher.update(buff), cipher.final()]);

    return re;
}

function encText(text, key, newIv, input_encoding, output_encoding) {
    checkKey(key);
    var iv = newIv || IV;
    if (cipherMode === ECB) iv = NULL_IV;
    var inEncoding = input_encoding || inputEncoding;
    var outEncoding = output_encoding || outputEncoding;
    var buff = new Buffer(text, inEncoding);
    var out = encBytes(buff, key, iv);
    var re = new Buffer(out).toString(outEncoding);
    return re;
}

function decBytes(buff, key, newIv) {
    checkKey(key);
    var iv = newIv || IV;
    var decipher = crypto.createDecipheriv(algorithm, key, iv);
    // decipher.setAutoPadding(false);
    decipher.setAutoPadding(true);
    var out = Buffer.concat([decipher.update(buff), decipher.final()]);
    // return pkcs5PaddingClear(out);
    return out;
}


function decText(text, key, newIv, input_encoding, output_encoding) {
    checkKey(key);
    var iv = newIv || IV;
    if (cipherMode === ECB) iv = NULL_IV;
    var inEncoding = input_encoding || inputEncoding;
    var outEncoding = output_encoding || outputEncoding;
    var buff = new Buffer(text, outEncoding);
    var re = new Buffer(decBytes(buff, key, iv)).toString(inEncoding);
    return re;
}

exports.setCipherMode = setCipherMode;
exports.setKeySize = setKeySize;
exports.encText = encText;
exports.encBytes = encBytes;
exports.decText = decText;
exports.decBytes = decBytes;

测试的代码为:test.js

    var aes = require('./aes.js');

var testTxt = 'ciika test node js aes';
var iv = new Buffer([0x2A, 0x9B, 0x36, 0x2A, 0xD6,0x9B, 0x9E, 0xD0, 0x72, 0xFB,0xFB, 0x75, 0xA9, 0xA8, 0x22,0x13]);
var key = new Buffer([0x82,0x5D, 0x9B, 0x3E, 0xC7, 0x08,0x4A, 0xC5, 0x41, 0xC3, 0xD5,0x5D, 0xA8, 0x6A, 0xEE, 0xA9]);
var enc = aes.encText(testTxt,key,iv);
console.log('enc:%s',enc);
aes.setKeySize(128);
enc = aes.encText(testTxt,key,iv,'ascii');
dec = aes.decText(enc,key,iv,'ascii');
console.log(dec)

测试结果为:
C:\ads>node test.js
enc:RpqaNAM2JKVdZg7VKknT6PmN/15BnhicYokPf1kcJV4=
ciika test node js aes

google pay消耗型支付的问题

GP支付的消耗型支付的大致流程为,先付款,付款后在消耗,如果该账户上存在没有消耗的商品,则必须先消耗,否则不能继续购买。同时在服务端可以根据token来校验和拿到相关的状态,请参考:https://developers.google.com/android-publisher/api-ref/purchases/products。
另外存在的一个问题是即使商品购买成功了,GP也很容易发生退款。

android的webview没办法使用非443端口的https

服务端的架构是采用docker直接采用端口映射,例如A docker暴露给外面的端口是443,B docker暴露给外面的端口是444,这里没有采用宿主机反向代理。所以相同的域名必须使用两个不同端口来区分开来,但是在实际使用过程中,android的webview没办法访问非默认端口,即非443的https的资源,但是如果把端口改成443即可,另外,webview也要修改一下才能使用HTTPS。
相关参考:
Getting a 400 bad request when using SSL on port other than 443?
http://stackoverflow.com/questions/19602092/getting-a-400-bad-request-when-using-ssl-on-port-other-than-443

解决android webview 中打不开https页面
http://www.apkbus.com/blog-89514-57591.html

android 上用WebVIew 访问非默认443的https网站会出现无法显示此网页
http://www.dewen.net.cn/q/15747/android+%E4%B8%8A%E7%94%A8WebVIew+%E8%AE%BF%E9%97%AE%E9%9D%9E%E9%BB%98%E8%AE%A4443%E7%9A%84https%E7%BD%91%E7%AB%99%E4%BC%9A%E5%87%BA%E7%8E%B0%E6%97%A0%E6%B3%95%E6%98%BE%E7%A4%BA%E6%AD%A4%E7%BD%91%E9%A1%B5