Intelligence without ambition is a bird without wings.

2016-05-31
C++-static

用法

  1. 全局作用域,声明或定义标识符(变量,函数),语义是该符号为内部链接

  2. 类定义中,声明方法时,说明该方法为静态方法

    • 静态方法可以访问该类对象的私有成员和方法!
  3. 类定义中,声明变量时,说明该变量为静态数据成员

  4. 函数定义中,说明该变量为静态变量,存储于数据段

阅读此文

2016-05-30
C++-sring-resize-reserve

区别

  • resize是调整string的size(length),操作后,[0, n)都可访问

    • 若大于原有长度,则填充对应字符,默认\0

    • 若小于原有长度,则截断

  • reserve是预留空间,以便快速插入,操作后,元素仍保持原样

    • 当大于原有容量(capacity),则引起重新分配过程
阅读此文

2016-05-28
C++-pointer-to-char

两层含义

  • C风格字符串(\0结尾),当使用这种语义时,只需传入该值即可。

    1
    void print_as_string(const char *s)
  • 字节数组(内容中可能包含\0),当使用此种语义时,还需传入长度

    1
    void print_as_hex(const char *s, size_t len)
阅读此文

2016-05-28
C++-StringPiece

背景

  • 很多时候,当传入一个字符串到函数时,往往只是读取字符串时

  • 若使用std::string,当实参为const char *时,会分配内存并拷贝该字符串以生成一个std::string

  • 当一个函数接受一个const std::string,而在该函数内部,又需要传递该值到另一个函数,则又需要重新生成一个std::string

目的

  • 当某个接口参数是接受字符串类型时,为了减少不必要的开销

  • 该类型可以接受const char *std::string,减少冗余代码编写

要点

  • StringPiece(google), StringRef(llvm), string_ref(boost),本质名,non-owning reference to a string

  • 通过隐式转换,方便地从const char*, std::string转换到此类型

  • 该类通过保存字符串指针和长度,来避免不必要的复制

  • 只支持非修改操作

  • 开销很低,只需要sizeof(const char*) + sizeof(size_t)字节

  • 支持所有的类容器操作

  • 因为StringPiece不拥有数据,所以确保在StringPiece生命期内,该数据可用

参考

  1. N3442: string_ref: a non-owning reference to a string.
  2. http://www.boost.org/doc/libs/1_60_0/libs/utility/doc/html/string_ref.html
  3. http://stackoverflow.com/questions/2172726/are-there-any-reasons-why-the-stringpiece-stringref-idiom-is-not-more-popular
阅读此文

2016-05-28
vim-出现^M

原因

  • ^M在vim中,是CR(回车符,0x0d)(:help digraph)

  • 原因是该文件内容混合了DOSUNIX格式,而vim识别为unix格式,则多余的换行符,就使用^M来显示

解决办法

  • 使用vim

    :%s;\r;;g
    
阅读此文

2016-05-28
C++-文件打开模式-binary-VS-text

说明

  • 在windows下,新建文件,默认文件格式为dos

  • 在Linux下,新建文件,默认文件格式为unix

text

  • 在windows平台下

    • 输出时,\n(0x0d)=>\r\n(0x0d 0x0a)

    • 输入时,\r\n(0x0d 0x0a)=>\n(0x0d)

测试

1
2
3
4
5
6
7
8
int main(int argc, char* argv[])
{

std::ofstream ins("test.txt"); // 默认`text`

ins << "a\n";

return 0;
}
  • linux
1
2
3
4
5
[I] /m/s/T/file od -Ax -t x1 test.txt 
000000 61 0a
000002
[I] /m/s/T/file file test.txt
test.txt: ASCII text
  • windows
1
2
3
4
5
[I] /m/s/T/file od -Ax -t x1 test.txt 
000000 61 0d 0a
000003
[I] /m/s/T/file file test.txt
test.txt: ASCII text, with CRLF line terminators

binary

  • 不对文件内容做任何转换

测试

1
2
3
4
5
6
7
8
int main(int argc, char* argv[])
{

std::ofstream ins("test.txt", std::ios_base::binary);

ins << "a\n";

return 0;
}
  • linux
1
2
3
4
5
[I] /m/s/T/file od -Ax -t x1 test.txt 
000000 61 0a
000002
[I] /m/s/T/file file test.txt
test.txt: ASCII text
  • windows
1
2
3
4
5
[I] /m/s/T/file od -Ax -t x1 test.txt 
000000 61 0a
000003
[I] /m/s/T/file file test.txt
test.txt: ASCII text
阅读此文

2016-05-28
C++函数参数类型

前提

  • 效率

  • 可读性

基本类型(int, char, …)

  • 传入,则pass by value

  • 传入传出,则pass by pointer

非基本类型

使用指针

  • 传出或传入传出参数,可以显式地知道该值会发生变化

  • 当参数可以接受NULL值时(若只作为传入,最好加上const)

  • 当返回一个新对象(new)的引用时,意味着,调用者需要释放该对象

  • 当作为类数据成员时

使用引用

  • 传入参数不可以为NULL

参考

  1. http://stackoverflow.com/questions/270408/is-it-better-in-c-to-pass-by-value-or-pass-by-constant-reference
  2. http://stackoverflow.com/questions/7058339/when-to-use-references-vs-pointers
阅读此文

2016-05-22
rsa

要点

  1. RSA是一种块加密,一个具体的RSA算法对应一个N(模数)

    块加密:

    • 密钥长度为工作长度

    • 明文不足,则需填充(一般都有几种填充方式)

    • 密文长度同密钥长度一致

  2. N(模数)的二进制位数,称之为RSA长度(对应openssl函数,RSA_size(rsa)),常用1024(128B),2048(256B)

  3. openssl genrsa 采用PKCS#8,使用PEM格式存储

  4. 公钥(N, E)

  5. 私钥(N, D)

  6. RSA(1024)的D:3, 65537(0x10001),当N值大于65537时,默认用65537!

RSA ASN.1定义

加密和签名

  1. 加密:公钥用来加密,私钥解密,保证信息被唯一持有私钥的接收((仅你可读但别人不可读,任何人都可写))

  2. 签名:私钥用来加密,公钥解密,保证信息是由唯一持有私钥的发送(仅你可写但别人不可写,任何人都可读)

填充模式

  1. RSA_PKCS1_PADDING (最常用的模式)

  2. RSA_PKCS1_OAEP_PADDING

  3. RSA_NO_PADDING

参考

  1. RSA算法原理–阮一峰
  2. https://en.wikipedia.org/wiki/65537_(number)
  3. https://www.openssl.org/docs/manmaster/crypto/RSA_public_encrypt.html
阅读此文

2016-05-15
图片存储

  • 客户端采用BASE64编码图片

方案1

服务端直接存储到数据库,客户端查询回去自行解码

优点

  • 服务器端实现简单

  • 服务器端不需要依赖具体编码方式

缺点

  • 相比二进制存储,多占用了33.3%空间

方案2

服务器解码后,存储二进制到数据库,客户端请求时再编码返回给客户端

优点

  • 节省空间

缺点

  • 服务端多做工作,而且浪费时间

  • 依赖客户端编码方式,可能会修改代码

方案3

服务器解码后,以文件形式存储到目录,客户端直接GET对应资源

优点

  • 无需存储到数据库

  • 客户端实现简单

缺点

  • 不安全,头像可能被直接访问到!
  • 数据迁移麻烦,万一路径地址改变,资料丢失等

结论

采用方案1.

阅读此文

2016-05-12
go-cmd

get

  • 自动获取所有依赖

    go get .
    

build

usage: go build [-o output] [-i] [build flags] [packages]

编译指定包,以及其依赖

  • 如果是main包,则在当前目录下生成一个可执行文件

run

usage: go run [build flags] [-exec xprog] gofiles... [arguments...]

编译并运行main

  • 如果main包是由多个文件构成,则需要都指定!

test

usage: go test [-c] [-i] [build and test flags] [packages] [flags for test binary]

自动测试指定包

  • 默认情况,会编译当前目录包以及相应测试,并运行测试

参考

  1. https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/01.3.md
  2. http://stackoverflow.com/questions/16935965/how-to-run-test-cases-in-a-specified-file
  3. http://stackoverflow.com/questions/19998250/proper-package-naming-for-testing-in-go-lang
阅读此文