写了个用于google两步验证的类,由于使用到Buffer和加密模块,所以仅可用于node
所有由罗佳(博主)发布的文章
[Javascript]base32编解码
用javascript写了个base32的编解码函数
const charTable=[
'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', '2', '3', '4', '5', '6', '7',
'='
],allowedPeddingCount=[6,4,3,1,0];
function str_split(str,length){
if(typeof str !== 'string')return [];
let a=[],i=0;
length||(length=1);
do{
a.push(str.substr(i,length));
i+=length;
}while(i<str.length);
return a;
}
const Base32={
encode:function(str,padding){
if(!str)return '';
let binaryString='';
for (let i = 0;i<str.length;i++) {
let bin=str.charCodeAt(i).toString(2);
binaryString+=('0'.repeat(8-bin.length)+bin);
}
let fiveBitBinaryArray=str_split(binaryString,5),base32='';
for(let i=0;i<fiveBitBinaryArray.length;i++){
let bin=fiveBitBinaryArray[i];
base32+=charTable[parseInt(bin+'0'.repeat(5-bin.length),2)];
}
let x=binaryString.length%40;
if (padding && x != 0) {
if (x == 8)base32+=charTable[32].repeat(6);
else if(x===16)base32+=charTable[32].repeat(4);
else if(x===24)base32+=charTable[32].repeat(3);
else if(x===32)base32+=charTable[32];
}
return base32;
},
decode:function(str){
if(!str)return '';
let paddingMatch=str.match(/\=+$/),
paddingCharCount=paddingMatch?paddingMatch[0].length:0;
if(allowedPeddingCount.indexOf(paddingCharCount)<0)return false;
for (let i=0;i<4;i++){
if (paddingCharCount===allowedPeddingCount[i]
&& str.substr(-(allowedPeddingCount[i]))!=charTable[32].repeat(allowedPeddingCount[i]))
return false;
}
str=str.replace(/\=+$/,'');
let binaryString = "";
for (let i=0;i<str.length;i+=8) {
let x='';
if (charTable.indexOf(str[i])<0)return false;
for (let j=0;j<8;j++) {
let bin=charTable.indexOf(str[i+j]).toString(2);
x+='0'.repeat(5-bin.length)+bin;
}
let eightBits=str_split(x,8);
for (let z = 0; z < eightBits.length; z++) {
let y,cd=parseInt(eightBits[z],2,10);
binaryString+=((y=String.fromCharCode(cd))||cd==48)?y:"";
}
}
return binaryString;
}
}
[PDF]いけないボーダーライン 平假名注音歌词
[Javascript]获取当前调用栈
用一个看起来似乎有点不恰当的办法,用Error对象
(new Error).stack
获取到的是字符串形式的调用栈。
不知道还有没有其它办法来获得调用栈。
买了个吉他
取名为GUItar,不想写代码的时候制造点噪音

【文档翻译】点击区域和无障碍访问
由于这篇文档原来不知道翻译的什么狗屁东西,而且还那么多人编辑过,我决定把它翻完。
MDN现在关闭注册了,如有不对请指出
https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility
网站搬家到Vultr
经过一晚上和半个上午的折腾,网站搬家到vultr了。
虽然是用docker部署的,不过由于mysql镜像有问题,我花了不少时间来研究是哪里出问题了,结果最后换了个镜像版本就好了。
就conoha那样态度恶劣自高自大的服务商,真的是不能省心得用,既然大家都从conoha逃走了,那我也逃走吧。
现在把那只vps当做ss节点用了,坐等被封。
服务器被Conoha封了一个下午,再用剁手
基友联动:https://www.blackglory.me/no-more-conoha/
今天中午收到了Conoha发来的邮件,说我的vps影响到了其它用户,已经被封了。
吃完饭立刻回了一封邮件问他们为什么被封了。
极路由HC5761A救砖日志2
极路由HC5761A救砖日志
事情的起因是这样的,我想给我的极路由HC5761A刷其它固件,但是怕刷成砖,于是发现了有breed这种可以让路由器刷不死的东西,于是我去极路由的论坛找了找确实有每个极路由对应的breed,然后我下载了HC5761的breed,因为那里并没有HC5761A的。。然后按教程刷进去,变砖了。
一个灯也不亮了。。。。
然后买了一套比路由器还贵的装备来修这个路由器
好的接下来开始救砖日志。
【佳佳拆解】极路由2
佳佳拆解之iPhone4
63图(2.87MB)
这只iPhone4由于触摸屏失灵,而且也不用了,所以我就把它拆了喵,顺便也期待着屏幕在装回去之后又能好起来。
结果是,装回去的时候不小心把电源键排线弄断了QAQ,然而触摸也并没有恢复OwO。。。。
总的来说,装回去以后比原来更废啦!
上上个星期买了个显示器
买了个飞利浦BDM3270显示器,由于用得太爽直到今天才发现忘了发图。。。。
这是一个32吋的显示器,收到货之后发现这尺寸比我想象中的大多了。。。宿管看见那箱子差点不让我搬进来
然后上一张图,为了显得它大,拍了张整个船坞的照片

这张全是麻点颜色发黄的照片是用完全没什么琴梨用的iPhone 6 Plus拍的。
由于它实在太大,想要放进最底层的格子里的话就没法装支架底座了,现在是斜着塞进去的,下面搞了一鼠标垫剪成两块卡在两边,加了个键盘稍微撑一下。鼠标是买屏幕送的,一般情况下就不用Arc Touch了。
[Node.js]让require搜索非当前文件路径的逐级路径
node的require函数有一个规则,就是参数是一个模块的名字的时候,它会从当前文件的目录开始,一级级往上级目录搜索node_modules文件夹以及里面对应名字的模块。
比如当前文件的目录是`/etc/miao/papapa/doge` ,在这个文件里面有一个`require(‘jiajia’)` ,那么require就会在以下位置寻找`jiajia`模块
/etc/miao/papapa/doge/node_modules /etc/miao/papapa/node_modules /etc/miao/node_modules /etc/node_modules /node_modules
但是我要在非当前文件路径逐级向上查找模块的话,就没法直接这样用require了。
但我又不想自己写循环来实现这个功能,于是我开始打node自带模块的主意,既然require有那样的特性,那就一定有处理逐级路径的函数,于是我开始读module模块的源码。在里面各种find变量,找到了`Module._nodeModulePaths` 这个函数,它的功能就是把一个路径分析成逐级路径的数组了。
然后又各种find,找到了处理require路径数组的地方,发现它是module.paths,那么问题解决了,只要用`Module._nodeModulePaths` 先把路径拆成逐级路径,然后和module.paths合并就可以了。
var p=module.constructor._nodeModulePaths('/etc/miao/papapa/doge');
module.paths=module.paths.concat(p);
这么一来就达到了require搜索非当前文件路径的逐级路径效果。
要注意的是module是当前context的实例,所以对它的操作不影响其父模块以及子模块,在这里修改的module.paths和其它模块无关,也就是说在其它模块会失去这个效果,除非在其它地方也执行以上代码。
我已经尝试了修改process.env[‘NODE_PATH’],因为源码里初始化module.paths的代码中也用到了这个环境变量,但是直接修改并没有什么用,到了子模块里依然是原来的NODE_PATH。
不知有没有办法让这个效果作用到全局。
[Node.js]拦截process.stdout和process.stderr
由于解决这个问题花了我一些时间,所以记录一下说不定可以帮到其他人。
process.stdout是一个getter,所以我们不能用普通的替换来换掉process.stdout来拦截写入它的数据。同时,process.stdout是一个Writable Stream,所以也不能简单地直接从它里面获取写入的数据。
一开始我花了不少时间来研究怎么可以从这个Writable Stream里读出数据,但是这似乎太麻烦了,然后我甚至想到了利用child process来拦截数据。最后发现其实很简单,我们只要重新定义这个Getter就可以了。
var stream=require('stream');
var rawStdout=process.stdout,//先拿到原来的stdout
newStdout=new stream.PassThrough();//创建一个passthrough流,这是一种特殊的Transform流,会直接把写入的数据吐出来
process.__defineGetter__('stdout',function(){//重新定义process.stdout的Getter
return newStdout;//返回我们的passthrough流
});
这样我们就成功拦截到标准输出了,要注意,这段代码必须放在有任何输出之前,一旦在之前有了内容输出,它就没用了。
然后我们就可以自己决定怎么处理stdout了比如:
newStdout.pipe(rawStdout);//内容输出到控制台 newStdout.pipe(文件的writable stream);//内容写入文件 newStdout.pipe(其它可写流);//随你怎么处理
同理,process.stderr也可以这样拦截
[Javascript]清空数组
var a=[123,234,345,567]; a.length=0;//清空了
上面的清空方式虽然非常不合字面含义,不过还确实清空了。。。
var a=[123,234,345,456]; a.splice(0);//清空了
这方法倒是符合字面含义了,不过这个操作会返回整个一个新的数组,所以可能性能不如上面的一种方法。
