0%

1. 查看签名

  • 提取签名
    jar xf HelloWorld.apk META-INF/CERT.RSA

  • 打印签名
    keytool -printcert -file CERT.RSA

  • 打印公钥,签名用的公钥
    keytool -printcert -file CERT.RSA -rfc,或者导出到一个文件keytool -printcert -file CERT.RSA -rfc > my_pub.key

相同的签名的不同版本APK应用相同的md5,sha1,sha256指纹,代表同一个公钥签名。

2. 查看public key的指纹

指纹就是用散列算法计算公钥的文本,rfc格式(带有-----BEGIN CERTIFICATE----------END CERTIFICATE-----)。

使用上面步骤得到的my_pub.key,验证md5。实际工作中不需要,工具都帮我们做好了。

1
2
3
openssl x509 -noout -fingerprint -md5 -inform pem -in my_pub.key
openssl x509 -noout -fingerprint -SHA1 -inform pem -in my_pub.key
openssl x509 -noout -fingerprint -SHA256 -inform pem -in my_pub.key

3. 查看keystore中的签名

keystore中有多个公钥秘钥对,一个对就是一个alias, 每个的访问密码不同。
keytool -list -keystore my.keystore -alias myAlias输入库密码可以看到公钥的指纹。

4. 给apk签名

jarsigner -verbose -keystore my.keystore -signedjar ma_app_signed.apk my.apk myAlias

5. Android Studio Debug签名

默认Android Stuido Debug时会自动签名(这个是IDE生成的,gradle命令行不会自动生成签名),用的keystore是没有密码的,但是有时候我们调试第三方登录,需要固定的签名,所以就自己生成签名,覆盖默认的Debug的签名。

5.1 生成Debug签名

$ keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname "C=US, O=Android, CN=Android Debug"
https://gist.github.com/henriquemenezes/70feb8fff20a19a65346e48786bedb8f
这里需要注意的是,如果用的JDK8里面的keytool生成的keystore是没有问题的。但是用JDK11里面的keytll生成keystore会报错:Invalid keystore forma。两种方案:

  • 用回JDK8的keytool生成keystore
  • 用Android Studio生成keystore
    Read more »

1.构造函数

1
2
3
4
5
6
7
8
function Foo(a){
if(!(this instanceof Foo)){
//非当前实例,原因是没用new去调用
return new Foo(a)
}
this.name = a
}
var foo = new Foo('foo') //这里加不加new一样,但是推荐加,不能保证每个人写的构造函数都会check instance

我记得构造函数首字母要大写,但是发现现在不大写也可以,最好大写吧。
new 的作用:

  • 绑定了this
  • 返回一个对象
  • 增加一个__proto__的属性指向构造函数的protoType

2.原型

2.1 继承

js中的继承是原型链,就是GrandFather grandFather<-Father father<-Son son.它们之间靠__proto__联系在一起。就是

1
2
3
son.__proto__ === Son.ProtoType
son.__proto__.__proto__ === Father.protoType
son.__proto__.__proto__ .__proto__ === GrandFather.protoType

由于js查找属性时,按照这个原型链去查,一直能查到祖父。

2.2 protoType __proto__

  • 相同点:
    protoType和__proto__对应的是同一个原型,它是一个Object。每个实例的__proto__都是构造函数用自己的protoType赋值的。
  • 不同点:
    不同点__proto__是实例调用的,protoType是构造函数调用的(注意:我没说是类,js本质上没类,只有对象和函数,每个实例都是构造函数构造出来的)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var p ={ 
isHuman: false,
name: 'foo',
}
function Glass(){
this.glass = 'glass'
}
var a = {}
// 不要直接给一个对象赋值__proto__,这个会导致性能问题,不是赋值的时候有问题,而是查找的时候有性能问题
a.__proto__ = p
// 1. 可以用原型来做
var b = new Glass()
b.__proto__.__proto__ = p // or Glass.protoType.__proto__ = p
// 2. 用Obejct.create()
var c = Object.create(p) // 这个没有影响任何构造函数

2.3 实例的属性

js的属性分为自己的(Object.getOwnerPropety())和继承的(Object.getPrototypeOf())
循环遍历属性有几个特殊的地方:

  • 如果使用for
    for会打印所有属性,包括自己的和继承的。
    1
    2
    3
    4
    // 使用上面的b这个例子
    for(let v in b){
    console(v) // isHuman, name, glass 都是可以打印出来的
    }
  • 使用Object.keys
    Object.keys只会打印自己的属性
    1
    Object.keys(b) //只会打印 isHuman, name

我很少写原生的js了,大部分是用TS,写多了TS,这些都忘记了。

1.事件三个阶段

  • capture,从DOM tree到节点target
  • target, 处理事件
  • bubble,事件冒泡,如果不stopPropagation或stopImmediatePropagation,那么一直到DOM

    preventDefaut()这里的Default会stopPropagation,不让冒泡。冒泡有时候很有用,如监听页面的点击,做分析报告。另一个好处是可以动态添加和移除节点,同时可以对它的事件监听。

Read more »

1. Electron vs NW.js

1.1 共同点

  • 都是使用chromium作为渲染工具,开发跨平台的客户端软件。
  • 完成的软件结构都是有两部分,native和web。前者是调用本地文件接口,网络等,实现底层功能,如数据库连接;后者和普通web开发一样。
  • 编写语言都是js, html, css

1.2 不同点

  • Electron的启动文件是一个js文件,在里面load一个index.html;NW.js是一个index.html。这是设计上的区别,Electron实现是不改chromium+node;NW.js修改chromium,以支持node的接口。
  • Electron的代码只可以混淆;NW.js可以改原生chromium的代码,安全性比Electron高。
Read more »

1.mysql-server升级

我用系统升级的提示框升级了,看到了升级了mysql-server到5.7,然后apt-get autoremove时,发现mysql-server的配置错了,在/etc/mysql/下有一个debian.cnf的配置文件,这个是mysql的维护用户,可以用来做profile的。按照里面的配置去mysql的数据库更新下密码就正常了。

注意mysql的密码插件的强度提示,可以手工降低后再修改密码。

1
2
3
4
5
6
# 首先登陆mysql命令行
mysql -u root -p
# 输入密码登陆后执行以下两个命令
set global validate_password_policy=0;
# 修改密码sys-debian-maint(maint就是maintenance缩写)
GRANT ALL PRIVILEGES on *.* TO `debian-sys-maint`@`localhost` IDENTIFIED BY 'your password' WITH GRANT OPTION;

之后还是手工升级保险一点。

Read more »

1. 去掉转换后的exports

由于phantomjs发现不了exports,所以需要把转换后文件的第一行去掉。方法是在ts文件最上面加上export = 0;
//issue: don’t add Object.defineProperty(exports, “__esModule”, { value: true });
//https://github.com/Microsoft/TypeScript/issues/14351

2. noEmit

"noEmit":true这个配置就不会产生输出文件了。

3. esModuleInterop配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"compilerOptions": {
"moduleResolution": "node",
"esModuleInterop": true, // 这个是node package引入的问题,如果是true,会引用default
"module": "commonjs",
"target": "es6",
"allowJs": true,
"outDir": "./build",
"noImplicitAny": false,
"sourceMap": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"strictNullChecks": true
},
"include": [
"./src/**/*"
],
"exclude": [
"node_modules"
]
}

当我们import xx from ‘module’时,等价于var xx = require(‘module’).default。
当我们import {A,B,C} from ‘module’时,等价于 var {A,B,C} = require(‘module’)

当我们export modue时,等价于 export.module = module
当我们export default module时, 等价于 export.default = module
当我们export = module时, 就是最特殊的情况,因为没有default了,也没有其它的export.xx了。

总结一下,node legacy没有那个default的概念,但是用TypeScript时有了这个default的概念,为了保持兼容性,就把这个esModuleInterop设置为true,起的效果就是当遇到没有default的情况,给它用{deault: moduel}包装下,那么都会有default这个值了,避免了default是undefined的情况。

1. 安装emacs

使用brew

1
brew install emacs --with-cocoa

C-h t # 打开tutorial

2. 配置emacs

原来是用的prelude,后来发现太重,反应有点慢。因为我主要是为了python,所以重新配置。参考了几篇文章:

  • Emacs:最好的Python编辑器?
    注意有几处不同,elpy的ipython配置现在是
    1
    2
    (setq python-shell-interpreter "ipython"
    python-shell-interpreter-args "-i --simple-prompt")
Read more »

1. nvm

nvm的目录是~/.nvm

1
nvm alias default 8.11.3 #使用node 8.11.3作为默认版本

1.1 特定node的目录

比如node 6.9.5的目录是
.nvm/versions/node/v6.9.5/lib/node_modules

2. yarn

npm模块的依赖,现在用yarn,它的缓存在~/.npm。

注意在安装nvm的情况下,不要再安装node了`brew install yarn –without-node

Read more »

1.原生模块

1.1Anroid

有三个NativeModule, JavaScriptModule, createViewManagers

2.IOS

应该有三个,导出模块或者原生View,都是用RCT_EXPORT_MODULE

2.Android原生View的显示bug

Android上,我发现一个View始终不显示,后来发现原因,是原生的View需要重绘,调用自己的requestLayout,再调用measureLayout

这个bug我找了好久,最后没办法试了一下,居然解决了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private final Runnable mLayoutRunnable = new Runnable() {
@Override
public void run() {
measure(
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
layout(getLeft(), getTop(), getRight(), getBottom());
}
};

@Override
public void requestLayout() {
super.requestLayout();

// The toolbar relies on a measure + layout pass happening after it calls requestLayout().
// Without this, certain calls (e.g. setLogo) only take effect after a second invalidation.
post(mLayoutRunnable);
}
  1. 使用原生自定义View,setState刷新界面后UI不能正常显示
  2. github issue