中信信用卡本期费用或利率计算方法

假设我们在
某日(假设为X)透支了 5000元。
在到期还款日之前某日(假设为Y)还了 4000元。
我们来计算一下到下期帐单日(假设为Z)出来的时候,本期费用是多少,就是该付多少的利息。
5/10000 这是日利率。
5000*(5/10000)*(Y-X) +
1000*(5/10000)*(Z-Y)

许多人可能认为我在还款日之前还了4000元,他就不应该算这4000元的利率了,其实不是。他们还在算,所以透支银行信用卡的钱最好最好是在还款日之前还掉。不然这利率还真够吓人的。

Socks5代理协议 Socks V5

Socks代理协议是作为【应用层】与【传输层】之间的一个中间层。

一、首先客户端向服务器端发起socks代理请求
+—-+———-+———-+
|VER | NMETHODS | METHODS |
+—-+———-+———-+
| 1 | 1 | 1 to 255 |
+—-+———-+———-+
上面的数字表示字节数。VER段为协议版本就是0×05,NMETHODS为后面METHODS的字节数量,每一个字节表示一种方法。

二、服务器回应给客户端
+—-+——–+
|VER | METHOD |
+—-+——–+
| 1 | 1 |
+—-+——–+
VER同样是版本号 0×05,METHOD为服务器端选择的方法,如果传递一个 0xFF,表示没有可以让服务器接受的方法,客户端此时就必须终止连接。

目前的传输方法有:

o X’00′ 无身份验证
o X’01′ GSSAPI
o X’02′ 用户名/密码
o X’03′ to X’7F’ IANA指派
o X’80′ to X’FE’ 保留私用的方法
o X’FF’ 无可接受的方法

三、客户端收到服务器的响应后,如果不是 0xFF,那就表示服务器可以接受客户端的代理请求。然后向服务器端发送
+—-+—–+——-+——+———-+———-+
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+—-+—–+——-+——+———-+———-+
| 1 | 1 | X’00′ | 1 | Variable | 2 |
+—-+—–+——-+——+———-+———-+
o VER 版本号: X’05′
o CMD 指令
o 连接 X’01′
o 绑定 X’02′
o UDP相关 X’03′
o RSV 保留的就设置为 0×00
o ATYP 地址类型
o IPv4地址: X’01′
o 域名: X’03′
o IPV6地址: X’04′
o DST.ADDR 目标地址
o DST.PORT 目标端口

如果地址类型为 IPV4,那么就会使用 4个字节分别表示 IP地址的4段。
如果地址类型为 域名,那么就第一个字节表示域名的长度,不用空字节来判断结束。
如果地址类型为 IPV6,那就么会用16个字节来表示IPV6地址。
比如这里我们以 域名 kejibo.com为例:
050100030a6b656a69626f2e636f6d0050
05就是版本号
01表示连接
00保留位
03表示地址类型,这里我们使用域名就是0×03
0a表示域名的长度这里我们是 kejibo.com刚好10个字节。0a就表示10个字节
6b656a69626f 表示 kejibo
2e表示 点
636f6d 表示 com
0050表示端口号 80

四、收到上面的请求后,服务器向客户端发送
+—-+—–+——-+——+———-+———-+
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+—-+—–+——-+——+———-+———-+
| 1 | 1 | X’00′ | 1 | Variable | 2 |
+—-+—–+——-+——+———-+———-+
o VER 版本号: X’05′
o REP 回复字段:
o X’00′ 成功
o X’01′ SOCKS服务器出错
o X’02′ 连接不合规则
o X’03′ 网络不可连接
o X’04′ 主机不可连接
o X’05′ 连接被拒绝
o X’06′ TTL 超时
o X’07′ 命令不可接受
o X’08′ 地址类型不可授受
o X’09′ to X’FF’ 未分配
o RSV 保留位 0×00
o ATYP 地址类型
o IP V4地址: X’01′
o 域名: X’03′
o IP V6 地址: X’04′
o BND.ADDR 服务器绑定的地址
o BND.PORT 服务器绑定的端口

客户端收到响应后,如果收到的回复是【成功】,那么就可以向服务器端发起常见的请求了,比如 http ftp smtp telnet之类的请求了,服务器端传发这些请求到目标服务器,然后把目标服务器的回应再转给客户端。

发送此篇文章就是通过Chrome,使用Chrome Switchy连接 自己写的一个Go语言的 socks代理服务器,发送出去的。
转载请注明:http://kejibo.com/socks5/

kloxo yum update升级后suphp 500 Internal Server Errors错误的解决方法

闲着没事的时候把一台kloxo面板的服务器yum update升级了一下,因为之前几次升级完全没有问题,所以这次也就没多想就yum update了。

不过yum update后,发现所有php网页都是显示500错误
“Internal Server Errors”。

因为网页从升级前到升级后一直没变过所以肯定不是网页权限的问题。

网上找到把web服务器换到lighttpd,再切换回httpd,还是老样子。

查看/var/log/httpd/suphp_log 文件,里面完全正常,都是一些 [info]信息,没有什么错误或警告。
类似于:
Tue Mar 13 16:48:15 2012] [info] Executing “/home/someone/domain.com/file.php” as UID 1075, GID 1075

所以suphp也应该是正常的。

查找 httpd log日志,找到一些错误信息,都一一下解决,发现问题依旧,所以也不是这个问题。

试了一下:
php-cgi 随便一个php文件。

出来神奇的错误信息:
I/O warning : failed to load external entity “/etc/php-fpm.conf”
Mar 13 16:09:45.354190 [ERROR] fpm_conf_init_main(), line 522: failed to load configuration file: failed to parse conf file

奇怪 kloxo php-5.2.17 不是没有使用php-fpm 吗?怎么出现这种错误,
在自己电脑上的 php-cgi 试了一下就不会出现这个 php-fpm 提示的错误,所以问题也有眉目了,应该是 php版本的问题。

于是:
yum downgrade php*
降级的这个几个包分别是
Downgrading:
php i386 5.2.17-1 lxcenter-updates 3.9 M
php-bcmath i386 5.2.17-1 lxcenter-updates 56 k
php-cli i386 5.2.17-1 lxcenter-updates 2.7 M
php-common i386 5.2.17-1 lxcenter-updates 231 k
php-devel i386 5.2.17-1 lxcenter-updates 544 k
php-gd i386 5.2.17-1 lxcenter-updates 318 k
php-imap i386 5.2.17-1 lxcenter-updates 95 k
php-mbstring i386 5.2.17-1 lxcenter-updates 1.3 M
php-mcrypt i386 5.2.17-1 lxcenter-updates 36 k
php-mhash i386 5.2.17-1 lxcenter-updates 18 k
php-mysql i386 5.2.17-1 lxcenter-updates 254 k
php-pdo i386 5.2.17-1 lxcenter-updates 151 k
php-xml i386 5.2.17-1 lxcenter-updates 305 k

然后再重启一下 httpd
service httpd restart 就行了。

chrome安装插件时显示Package is invalid: ‘CRX_SIGNATURE_VERIFICATION_FAILED’问题的解决方法。

Google Reader G+化改版后,颜色更单一,更刺眼了,对于重度使用者来说这非常伤眼睛,而今天正好发现出了一个 Reeder for Chrome 的插件。当然不能错过了。这其实只是GR的皮肤,原GR的功能都是完整的。

但是进入网站安装的时候发现提示

原以为可能是新出的插件不适合老版本chrome使用,于是将浏览器升级chrome 16 beta(也正好想体验一下它的多用户功能)。但是重试后发现问题还是一样。

搜索一翻后在code.google上找到问题的原因居然是没有清缓存引起的,于是清缓存,安装一切正常。

typecho转换到wordpress

typecho快一年多没有更新过了,虽然使用感觉还算不错,不过还是经不住wordpress庞大插件库的诱惑,因为博客本来就没有多少流量,所以也不担心负载的问题,所以就把博客转换到wordpress了。特此做一记录。
使用的转换程序都是网上找的。
转换程序适合:typecho0.8 (10.8.15)到wordpress3.03版本。
typecho2wordpress
WordPress.v3.0.3.Incl.Simp.Chinese.Pack.v1-wpcng
可转换内容:
1、博客
2、附件
3、评论
4、分类
5、标签
转换步骤:
1、在原typecho博客的主机上安装wordpress3.03版本。
2、上传typecho2wordpress转换程序,开始转换。
3、转换完后,将原typecho里面的 /usr/uploads下面的附件放到 wordpress的 /wp-content/uploads 里面。

转换后残留问题:
1、打开wordpress的媒体库,看不到图片,这是因为转换程序将附件记录的里面 post_status 没有设置成 inherit.将 post_type为attachment的posts的post_status属性改为 inherit。
2、博客文章里面的图片及附件链接没有更新,比如typecho附件的图地址为/attachment/id 图片地址为 /usr/uploads/*** 需要更新为wordpress的 /wp-content/uploads/***

于花了一点时间稍微修改了一下转换程序:
typecho2wordpress-kejibo
使用前请自行备份数据库,如果造成任何损失,本人概不负责!
成功转换到 wordpress3.03后,通过wordpress后台自动更新到wodpress最新版本3.21完全没有问题。

XZ压缩最新压缩率之王

xz这个压缩可能很多都很陌生,不过您可知道xz是绝大数linux默认就带的一个压缩工具。

之前xz使用一直很少,所以几乎没有什么提起。

我是在下载phpmyadmin的时候看到这种压缩格式的,phpmyadmin压缩包xz格式的居然比7z还要小,这引起我的兴趣。

最新一段时间会经常听到xz被采用的声音,像是最新的archlinux某些东西就使用xz压缩。不过xz也有一个坏处就是压缩时间比较长,比7z压缩时间还长一些。不过压缩是一次性的,所以可以忽略。

xz压缩文件方法或命令

xz -z 要压缩的文件

如果要保留被压缩的文件加上参数 -k ,如果要设置压缩率加入参数 -0 到 -9调节压缩率。如果不设置,默认压缩等级是6.

xz解压文件方法或命令

xz -d 要解压的文件

同样使用 -k 参数来保留被解压缩的文件。

创建或解压tar.xz文件的方法

习惯了 tar czvf 或 tar xzvf 的人可能碰到 tar.xz也会想用单一命令搞定解压或压缩。其实不行 tar里面没有征对xz格式的参数比如 z是针对 gzip,j是针对 bzip2。

创建tar.xz文件:只要先 tar cvf xxx.tar xxx/ 这样创建xxx.tar文件先,然后使用 xz -z xxx.tar 来将 xxx.tar压缩成为 xxx.tar.xz

解压tar.xz文件:先 xz -d xxx.tar.xz 将 xxx.tar.xz解压成 xxx.tar 然后,再用 tar xvf xxx.tar来解包。

oauth2开放认证协议原理及案例分析

之前翻译过一篇
OAuth认证协议原理分析及使用方法
,虽然 OAuth2还没有正式发布,但是国内外的OAuth2的采用情况几乎要完全替代掉OAuth1.1了。像淘宝、腾讯、人人网、百度开放平台就已经采用Oauth2,新浪微博也发来邮件说是要很快上马OAuth2,彻底替换掉OAuth1.1。目前OAuth2到了
v20草稿阶段
,最新的版本是 2011年7月25号发布的,协议变化还是很快的,所以看到国内的一些已经实现的实例,再比照官方的 oauth2,会有些出入的。

为何要 OAuth2来替换OAuth1.1?

  • 一、OAuth2大大简化了认证流程,OAuth1版本,我都感觉有些流程设计不是为安全性而存在,有些东西很难想一个理由,他们为何要弄得如此复杂。复杂可能是增加安全性的一个要素,但是也极大增加了开发者的开发难度。
  • 二、增加了对多种不同方式的认证,原来的认证只能直接或间接通过浏览器,现在有专门的标准来给客户端程序、移动应用、浏览器应用提供认证的方法。

OAuth2的四种角色

  • resource owner资源所有者:比如twitter用户,他在twitter的数据就是资源,他自己就是这些资源的所有者。
  • resource server资源服务器:保存资源的服务器,别人要访问受限制的资源就要出示 Access Token(访问另牌)。
  • client客户端:一个经过授权后,可以代表资源所有者访问资源服务器上受限制资源的一方。比如 开发者开发的应用。
  • authorization server授权服务器:对 资源所有者进行认证,认证通过后,向 客户端发放 Access Token(访问另牌)。

OAuth2取得Access Token的四种方式

  • 一、Authorization Code授权码方式:这种是推荐使用的,也是最安全的,也是替换OAuth1.1的一种授权方式。
    流程:
    1、引导用户访问授权服务器,比如地址:

        GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
            &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
        Host: server.example.com
    

    ,其中response_type 值固定为 code,client_id就是客户端申请开发者的时候取得的 appkey,state是一个可选参数,可以用于保存客户端在引导用户转向前的一些状态,当回到 redirect_uri的时候会原封不动的传回来,redirect_uri是当用户确认授权应用访问的时候跳转回来的地址。
    2,用户同意授权后跳转回来的的地址如:

         HTTP/1.1 302 Found
         Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
                   &state=xyz
    

    &state=xyz ,其中 code就是 Authorization Code,state就是上面所说的可选参数。
    3,使用取得的 Authorization Code去换取Access Token:

         POST /token HTTP/1.1
         Host: server.example.com
         Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
         Content-Type: application/x-www-form-urlencoded;charset=UTF-8
    
         =authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
         &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
    

    其中 Authorization是由Client id(app key)及Client password(app secret)组合成的 http basic 验证字符串,grant_type必须为 authorization_code,code是上一步取得的 Authorization Code,redirect_uri是完成后跳转回来的网址。
    如果Client不能发送 Authorization信息,则可以使用下面的方式,/token这个地址必须是 https连接的,不然就有泄露 client secret的可能性:

         POST /token HTTP/1.1
         Host: server.example.com
         Content-Type: application/x-www-form-urlencoded;charset=UTF-8
    
         grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
         &client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw
    

    成功的话返回的信息为:

         HTTP/1.1 200 OK
         Content-Type: application/json;charset=UTF-8
         Cache-Control: no-store
         Pragma: no-cache
    
         {
           "access_token":"2YotnFZFEjr1zCsicMWpAA",
           "token_type":"example",
           "expires_in":3600,
           "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
           "example_parameter":"example_value"
         }
    
  • 二、Implicit Grant隐式授权:相比授权码授权,隐式授权少了第一步的取Authorization Code的过程,而且不会返回 refresh_token。主要用于无服务器端的应用,比如 浏览器插件。隐式授权不包含Client授权,它的授权依赖于 资源所有者及注册应用时候所填写的redirection URI(跳转地址)。因为Access token是附着在 redirect_uri 上面被返回的,所以这个 Access token就可能会暴露给 资源所有者或者设置内的其它方(对资源所有者来说,可以看到redirect_uri,对其它方来说,可以通过监测浏览器的地址变化来得到 Access token)。
    流程
    一、引导用户访问一个专门的授权页面,如

        GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
            &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
        Host: server.example.com
    

    这里的 response_type为 token,client_id为appkey。可以看到这里取Access token的过程中并没有像 第一种方式那样传入 client_secret。因为如果你传入 client_secret,其实就是相当于告诉用户,你应用的app secret了。
    二、在成功授权后,跳转回到 redirect_uri所定义的网址

         HTTP/1.1 302 Found
         Location: http://example.com/rd#access_token=2YotnFZFEjr1zCsicMWpAA
                   &state=xyz&token_type=example&expires_in=3600
    

    ,这样应用就可以通过取地址中的 fragment部分来取得 access token。

  • 三、Resource Owner Password Credentials资源所有者密码证书授权:这种验证主要用于资源所有者对Client有极高的信任度的情况,比如操作系统或高权限程序。只有在不能使用其它授权方式的情况下才使用这种方式。
    流程:
    一、提交信息到取 token页面

         POST /token HTTP/1.1
         Host: server.example.com
         Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
         Content-Type: application/x-www-form-urlencoded;charset=UTF-8
    
         grant_type=password&username=johndoe&password=A3ddj3w
    

    这里的 Authorization是 client_id为username,client_secret为password的http basic验证码。grant_type必须为 password,username为用户名,password为用户密码。
    取得的结果如下:

         HTTP/1.1 200 OK
         Content-Type: application/json;charset=UTF-8
         Cache-Control: no-store
         Pragma: no-cache
    
         {
           "access_token":"2YotnFZFEjr1zCsicMWpAA",
           "token_type":"example",
           "expires_in":3600,
           "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
           "example_parameter":"example_value"
         }
    

    Q:为何要这种这么不安全的方式?
    A:取代原来原始的 username,password的授权方式,而且不需要 client保存用户的密码,client只要保存access token就可以。主要用于客户端程序。

  • 四、Client Credentials客户端证书授权:这种情况下 Client使用自己的 client证书(如 client_id及client_secret组成的 http basic验证码)来获取 access token,只能用于信任的client。
    流程:
    一、提交参数取 access token

         POST /token HTTP/1.1
         Host: server.example.com
         Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
         Content-Type: application/x-www-form-urlencoded;charset=UTF-8
    
         grant_type=client_credentials
    

    其中 Authorization是client_id及client_secret组成的 http basic验证串。grant_type必须为client_credentials,
    返回如下:

         HTTP/1.1 200 OK
         Content-Type: application/json;charset=UTF-8
         Cache-Control: no-store
         Pragma: no-cache
    
         {
           "access_token":"2YotnFZFEjr1zCsicMWpAA",
           "token_type":"example",
           "expires_in":3600,
           "example_parameter":"example_value"
         }
    

国内一些oauth2案例分析

标准的 oauth2中,使用 access token来向资源服务器发出请求,取得资源。这里的资源服务器需要使用 https协议,否则access token极可能被其它方获取。比如

     GET /resource/1 HTTP/1.1
     Host: example.com
     Authorization: Bearer 7Fjfp0ZBr1KtDRbnfVdmIw


bearer是指 token类型
,后面的字符串就是access token。还有一种
mac类型的 token(目前v20版本的草稿里还没有文档)
,如:

     GET /resource/1 HTTP/1.1
     Host: example.com
     Authorization: MAC id="h480djs93hd8",
                        nonce="274312:dj83hs9s",
                        mac="kDZvddkndxvhGRXZhvuDjEWhGeE="

,因为 https速度相较http慢,而且并非所有服务器或客户都支持https,所以国内一些网站采用一种http也可访问资源的方式。


淘宝开放平台的方式
:应用通过用户授权获取的AccessToken的值即等同于Sessionkey,应用凭借AccessToken调用taobao API即可。查看淘宝SDK,可以看到 其使用应用的app_secret作用密码钥来进行签名,参数里面包含了 这个Sessionkey,这样淘宝在收到这个请求的时候,根据 app_id来判断是哪个应用,根本sessionkey的值来判断是哪个用户,如果不传这个 sessionkey就用 app_id查得app_id所属的淘宝用户就行了。也就是说 sessionkey必须配合 这个 client自己的授权资料appkey appsrecet来访问资源。


百度开放平台方式

人人网方式
、还有腾讯也类似:在返回 access token的同时返回 sessionKey及sessionSecret。如:

{
    "access_token": "1.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-2346678-124328",
    "expires_in": 86400,
    "refresh_token": "2.385d55f8615fdfd9edb7c4b5ebdc3e39.604800.1293440400-2346678-124328",
    "scope": "basic email",
    "session_key": "9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A=",
    "session_secret": "27e1be4fdcaa83d7f61c489994ff6ed6",
}

在调用资源API的时候,如下:

GET /rest/2.0/passport/users/getInfo?session_key=9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A%3D&timestamp=2011-06-21+17%3A18%3A09&format=json&uid=67411167&sign=d24dd357a95a2579c410b3a92495f009 HTTP/1.1
Host: api.example.com

这里参数里面的 session_key,传给服务器后,用户查询 session_secret,sign使用session_secret作为密钥来加密的。可以看到这里调用的时候没有使用 client_id或client_secret信息,所以对于任何获取

    "session_key": "9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A=",
    "session_secret": "27e1be4fdcaa83d7f61c489994ff6ed6",

的一方都可以调用到API。降低系统耦合度。

Golang跟C语言一样没有C++所特有引用参数概念

看一下C++的引用参数:

#include 

void test(int &x)  //引用参数
{
    x = 99;
}

int main()
{
    int a = 1;
    test(a);
    printf("%c", a);
    return 0;
}

纯C中如果想实现这种函数内对外部传入参数值的修改,只能这样:

#include 

void test(int* x)   //指针参数
{
    *x = 99;
}

int main()
{
    int a = 1;
    test(&a);
    printf("%c", a);
    return 0;
}

Go语言也像C一样,没有引用参数的概念:

package main

func test(x *int) {  //指针参数
	*x = 99
}

func main() {
	a := 1
	test(&a)
	println(a)
}