解决 Macbook Air 风扇噪音问题

macbook fix noise

Macbook Air 风扇噪音问题由来已久, 我最早的那台 Macbook Air Early 2008 一直就有发热导致的噪音问题, 之后再换的 i7 的 Macbook Air 虽然没有之前的发热问题, 但噪音问题却还依旧. 乘着这次升级 Mountain Lion 的机会整理下解决方法.

Sublime Text 常用插件和设置

ubuntu develop mac tools sublime-text-2

从 Textmate 迁移到 Sublime Text 2 也不少时间了, 也对 Sublime Text 2 进行了不少研究了, 整理下这段时间我的常用的插件和配置.

我会定期的把自己常用的插件更新到这里. 也方便刚接触 Sublime Text 的人可以更好的设置自己的编辑器.

基础设置

打开 Sublime Text 2 后, 可以在菜单中找到 Preferences -> Settings - User 点击后, 会打开一个编辑器窗口. 在该编辑器窗口下, 就可以输入当前用户的关配置了. 我一般配置如下:

"draw_white_space": "all", // 显示空白字符, 比如 空格 tab
"font_size": 13.0,         // 字体大小
"scroll_past_end": true,   // 当文件到末尾时还能继续滚动
"trim_automatic_white_space": false  // 关闭自动删除每行前后空格

这里需要注意的是行尾的 , 需要符合标准的 json 格式.

另外用户配置文件会默认存放于 ~/Library/Application Support/Sublime Text 2/Packages/User 当然这时 mac 系统的存放位置, 其他操作系统请自行查找.

Package Control

Package Control 是用来管理 Sublime Text 2 的插件的插件. 也是装完后第一个要安装的插件.

首先打开 ctrl+`, 并在打开的 st2 console 中输入:

import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'

安装完成后, 应该就可以看到菜单下有 Preferences -> Package Settings 选项了.

常用插件

上面的 Package Control 安装完以后, 就可以通过快捷键 command + shift + p 并输入 install package, 来选择需要安装的插件.

Alignment

这插件用于对齐代码赋值语句, 例如:

var name = "sublimt"
var version = "2.0.1"
var title = "sublime text"

按下快捷键后, 会变成:

var name    = "sublimt"
var version = "2.0.1"
var title   = "sublime text"

不过这插件默认使用的是 ctrl + cmd + a 和 那个抢了 5个全局个快捷键的QQ冲突, 所以需要修改插件的快捷键. 点击菜单 Preferences -> KeyBindings - User, 加入如下内容

{ "keys": ["super+ctrl+alt+]"], "command": "alignment" }

将快捷键修改成 ctrl + opt + cmd + ], 要改成什么其他的也请自行修改.

ColorPicker

支持在各个平台下取色(window, mac, ubuntu) 插件, 输入 cmd + shift + c 开启, 相当好用.

Ctags

简单的说可以在代码里直接查看函数定义的地方, 比如看一个函数的定义或者类的定义. 不过这个插件无法在 mac 下生成 ctags 文件, 貌似是 python 层面的问题.

不过如果做 Ruby 开发的话可以装我写 guard-sublime-ctags, 这个 gem 会自动生成对应的 ctags 文件, 就可以在代码中按 ctrl + opt + ] 查看定义了.

DetectSyntax

自动检测写文件内容, 切换到对应的正确的语言, 如 Gemfile => ruby.

EncodingHelper

提供个菜单将 例如 gb2312 编码的文件, 转换成 utf-8 编码的文件.

JsFormat

用于格式化 javascript 的代码, 之后可以 cmd + shift + pFormat: javascript 就可以了.

MarkdownEditing

在 Markdown 编辑格式上, Sublime Text 2 还是无法于 Textmate2 或者 Mou 相比, 但因为快捷键不用熟悉, 所以强烈推荐该插件. 效果可以看如下的截图

 MarkdownEditing Preview

具体的安装步骤请参考: http://lucifr.com/2012/07/12/markdownediting-for-sublime-text-2/

SideBarEnhancements

默认 Sublime Text 2 新建文件的时候需要保存才能选择存放位置, 而装了这个插件就可以先建文件在编辑内容了, 当然这个插件还有一对其他功能. 比如: 在 Finder 中打开当前文件之类的功能.

Tag

编写 html 或者 xml 的时候, 这个插件可以自动关闭打开的标签.

ToggleQuotes

选中内容后可以在单双引号之前切换.

rsub

模仿 Textmate 2 的 rmate 让用户远程编辑服务器上的文件. 应该会挺好用的但我还没用过只是列在这里.

Rails 类插件

Rails Latest Migration

打开最后一个生成的 migration 文件, cmd + shift + p 里找 Latest Migration.

ERB Insert and Toggle Commands

让 Textmate2 里的 ctrl + shift + < 快捷键可以在 Sublime Text 下使用, 用于 ERB 下快速生成 <% %> 标签.

SCSS

插件本身通过 Package Control 安装就是了, 只是装好以后没有原先 CSS 的代码补全没了, 所以就需要自己复制一份 css 的自动补全放到用户目录下也就是放到用户配置目录下.

还需要稍微修改下, 具体的可以看我修改好的文件 scss_completions.py

isoD

Textmate 中还有一个我很常用的功能就是 输入 isoD<tab> 可以补全成当天的日期 2012-07-22, 找了半天也没发现有插件实现了类似的功能, 所以只能自己写一个加入到用户配置目录下了, 具体的可以看 timestamp.py

最后

最后我自己的 Sublime Text 2 的配置文件, 都会提交到 https://github.com/sunteya/sublime-user-package 不过不推荐直接使用, 但可以拿来做自己配置的参考.

在 Mac 上搭建 Ruby on Rails 开发环境

guide rails postgresql mac ruby mountain-lion xcode homebrew

近期 Apple 就应该会发布新版本的操作系统了 Mountain Lion, 而目前推出的 GM 版本不出意外也应该是最终发行的版本.

这里我们会在一台全新的 mac 上搭建 rails 开发环境, 使用的软件版本如下:

  • OS X Mountain Lion 10.8
  • rvm 1.14.5
  • Ruby 1.9.3-p194
  • Postgresql 9.1.4

可能实际安装的版本和目前不同, 所以需要根据实际环境来修正安装步骤. 另外还需要对 mac 系统的终端有一定的了解.

java 和 ruby 中使用 rsa 签名和验证数据

ruby openssl rsa java pem der

最近在做项目的支付接口, 需要对传输数据做签名以确保数据安全, 本以为只要有私钥和公钥签名应该挺简单的, 调2个函数就能搞定的事情. 但做了才发现这还是挺复杂的。

本以为收到的会是像 ssh 的 pem 证书一样的 公钥和私钥

-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAJ7vDNqDsv9RyD7CN0vXwLZBKvYWVHG9oirrmSldRUmCOWik88Me8anr
v4tXI2C1NFbnk6C1o6cM1kkeqEQSXQ3DSdHOOPmoTvHNwGR+C2FJHuuLR8YPraIr
oi8DpQzJl3qVdq0m0XmflDboGd+Cijb6z+oVrWtZ9KKssiI2glhLAgMBAAE=
-----END RSA PUBLIC KEY-----

但实际收到的却是

308189028181009EEF0CDA83B2FF51C83EC2374BD7C0B6412AF6165471BDA22AEB99295D4549823968A4F3C31EF
1A9EBBF8B572360B53456E793A0B5A3A70CD6491EA844125D0DC349D1CE38F9A84EF1CDC0647E0B61491EEB8B47
C60FADA22BA22F03A50CC9977A9576AD26D1799F9436E819DF828A36FACFEA15AD6B59F4A2ACB2223682584B020
3010001

ruby 完全无法读取这个公钥, 完全不知道这个串是咋生成的, 要来对方源代码才发现这个串其实是 java 中生成的公钥的16进制的显示内容. 而 java 默认生成的公钥和私钥都是 der 的二进制格式的. 所以首先是需要把收到的东西还原成标准的 der 证书. ruby 可以很简单的通 过一行代码转换成标准的 der 证书文件.

File.open("rsa_pub.der", "w") {|f| f << [ File.read("rsa_pub.key") ].pack("H*") }

这样我们得到 java 标准的 der 证书, 这时通过 ruby 自带的 openssl 库已可以读取公钥文件, 但是却始终无法读取私钥的der文件. 所以还是需要把证书转到到常用的 pem 格式供 ruby 读取. 方便的是 openssl 库已经提供了转换命令了.

转换 der 到 pem

我们可以通过 openssl 命令

openssl pkcs8 -nocrypt -inform der -in rsa_pri.der -outform pem -out rsa_pri.pem

将私钥转换成 pem 格式, 还可以通过

openssl rsa -pubin -inform der -in rsa_pub.der -outform pem -out rsa_pub.pem

将公钥也转换成 pem 格式.

测试代码

至此我们就得到了 ruby 常用的 pem 格式的密钥了. 接下来写段程序测试下这 2个 pem 是不是和 java 读取的一样.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.io.*;
import java.security.*;
import java.security.spec.*;

public class KeyTest {
	public static void main(String[] args) throws Exception {

		// use private key sign "abc" string
		byte[] priBytes = readBytes(new File("rsa_pri.der"));		
		KeyFactory factory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = factory.generatePrivate(new PKCS8EncodedKeySpec(priBytes));
		Signature signer = Signature.getInstance("SHA1WithRSA");
		signer.initSign(privateKey);
		signer.update("abc".getBytes("utf-8"));
		byte[] sign = signer.sign();
	
		System.out.print("sign is : ");
		for (byte b : sign) { System.out.print(String.format("%02x", b & 0xFF));	}
		System.out.println();
	
		// use public verify "abc" string
		byte[] pubBytes = readBytes(new File("rsa_pub.der"));
		PublicKey publicKey = factory.generatePublic(new X509EncodedKeySpec(pubBytes));
		Signature verifier = Signature.getInstance("SHA1WithRSA");
		verifier.initVerify(publicKey);
		verifier.update("abc".getBytes("utf-8"));
		boolean result = verifier.verify(sign);
		if (result) {
			System.out.println("verify successful!");
		} else {
			throw new RuntimeException("verify failed!");
		}
	}

	private static byte[] readBytes(File f) throws Exception {
		FileInputStream fis = new FileInputStream(f);
		byte[] bytes = new byte[(int) f.length()];
		fis.read(bytes);
		fis.close();
		return bytes;
	}
}

运行后我们可以看到输出了

sign is : 0f323518c49577bee82cbf70dd984d2601666d3939fe9efb89142227d8baf0b07751a47cceab6cd14e6feea92af4f8b20fe8bde27ddf0dc02248fb067f82b322af13f5b7e13a0e0680b3c57d989dfa0446350b52a027d8361179556d80c41e69d2f69224c99d0c6f90b158bbde37de3e1f8da91c2e8eef184f0175a58624da12
verify successful!

我们再用 ruby 实现同样逻辑的代码

1
2
3
4
5
6
7
8
9
require "openssl"

pri = OpenSSL::PKey::RSA.new(File.read("rsa_pri.pem"))
sign = pri.sign("sha1", "abc".force_encoding("utf-8"))
puts "sign is : #{sign.unpack('H*').first}"

pub = OpenSSL::PKey::RSA.new(File.read("rsa_pub.pem"))
result = pub.verify("sha1", sign, "abc".force_encoding("utf-8"))
puts "verify #{result ? 'successful!' : 'failed!'}"

运行后可以看到同样打印出了

sign is : 0f323518c49577bee82cbf70dd984d2601666d3939fe9efb89142227d8baf0b07751a47cceab6cd14e6feea92af4f8b20fe8bde27ddf0dc02248fb067f82b322af13f5b7e13a0e0680b3c57d989dfa0446350b52a027d8361179556d80c41e69d2f69224c99d0c6f90b158bbde37de3e1f8da91c2e8eef184f0175a58624da12
verify successful!

转换 pem 到 der

当然有时候我们还需要将 ruby 中生成的 pem 转换成 java 可以读取的 der 格式, 这个同样可以使用 openssl 命令

openssl pkcs8 -topk8 -nocrypt -inform pem -in rsa_pri.pem -outform der -out rsa_pri.der

这样就可以生成 java 可以读取的私钥 der 文件, 对于公钥我们既可以通过公钥的 pem 生成

openssl rsa -pubin -inform pem -in rsa_pub.pem -outform der -out rsa_pub.der

也可以直接通过私钥生成对应的公钥 der 文件

openssl rsa -inform pem -in rsa_pri.pem -pubout -outform der -out rsa_pub.der

写在最后

之前一直认为不会有多少困难的签名和验证, 也花了大半天才搞明白 java 和 ruby 之间的不同. 另外也严重鄙视下那家支付公司的愚蠢文档和一问三不知的技术人员.

代码里测试的证书可以到 这里下载

顺便说一句, 这例子也充分体现出, 不同语言之间代码行数的巨大差别. 从语法上来说 java 却是该被淘汰了.

参考文章

在 Ubuntu 上搭建 git 仓库服务器

linux guide server ubuntu git gitolite develop

安装 gitolite

git 服务器软件一般常用的曾经是 gitosis, 不过 gitosis 从 2009年就没人维护了, 目前推荐的是使用 gitolite.

再 Ubuntu 上安装 gitolite 非常简单, 只需要再命令行输入

apt-get install gitolite

就安装完成了. 比起之前的 gitosis 简单了不少.

初始化 gitolite