为 nginx 配置 https

为了给全站加上https,需要先获得一个经过CA签名的证书,恰好startssl提供免费的证书,所以我就有了折腾https的机会。

首先,要在本地生成一个证书:

openssl req -newkey rsa:2048 -keyout yourname.key -out yourname.csr

一定要记好生成key的密码,在启动nginx的时候需要用到,执行完之后就获得了一个csr文件,把这个csr文件上传到startssl,就可以获得被startssl签名的证书:

然后把自己生成的key和在startssl,把这两个文件copy服务器上

cp 1_api.updev.cn_bundle.crt /usr/local/nginx/conf/server.crt
cp api.key /usr/local/nginx/conf/server.key

在nginx的server里配置:

ssl on;
ssl_certificate /usr/local/nginx/conf/server.crt;
ssl_certificate_key /usr/local/nginx/conf/server.key;

并把之前监听80端口改为监听443端口,之后重启nginx,这时会提示输入Enter PEM pass phrase,需要输入之前生成key文件时设置的密码,完成后,nginx重启成功。

这时便完成了https的配置。

然而,在重启nginx的时候却需要输入两次密码,比较蛋疼,而且使用daocloud或七牛的https时,带密码的key是不被支持的,所以我们可以生成一个不带密码的key,这样可以避免每次重启nginx都需要输入密码。而且也可以使用daocloud和七牛的https功能。

我们可以使用 openssl rsa -in server.key -out server.key.unsecure命令来生成一个不带密码的key,然后把server.key.unsecure按照之前的配置就可以了。

而使用daocloud的https时,需要提供startssl签名的crt文件(nginx版)和不带密码的key,这样就可以了。

2016/07/20 12:29 下午 posted in  坏笔记不如好记性

一个微信红包问题

在V2上看到一个问题:
将 100 元的红包分为 10 份,每份最低 5 元最高 15 元,金额精确到 0.01 元。那么如果算法没问题的话,每个人的期望值自然是平均值,即 100 元 /10 人=10 元 /人。

说下我大体的思路,我们可以把总金额设定为sum,人数为n,那么,要满足这个条件可以:
5n<=sum<=15n
也就是说,如果随机一个金额的话:
5(n-1)<=sum-randNum<=15(n-1)
化简一下:
sum-15(n-1)<=randNum<=sum - 5(n-1)

def comp(sum=100, n=10): 
    result = [] 
    while n > 1: 
        min = sum - 15 * (n - 1) if sum - 15 * (n - 1) >= 5 else 5
        max = sum - 5 * (n-1) if sum - 5 * (n-1) <= 15 else 15 
        rand = random.uniform(min, max) 
        rand = round(rand, 2) 
        result.append(rand) 
        sum -= rand 
        n -= 1 
        result.append(round(sum, 2)) 
    return result 
2016/07/14 12:29 下午 posted in  坏笔记不如好记性

两个数交换操作

如果给你两个整型变量,然后交换两个整数,你有多少种方法?

中间变量法

最常用的方法,就像两个杯子之间倒换水一样,先找个中间变量,然后倒换。

import java.util.Scanner;
public class Main {

    public static void main(String[] args) {

        Scanner s = new Scanner(System.in);
        int num1 = s.nextInt(),num2 = s.nextInt();

        int tmp = num1;
        num1 = num2;
        num2 = tmp;

        System.out.println("num1 = " + num1 + 't' + "num2 = " + num2);
    }
}

 作差法

作差法的好处就是可以少开一个变量,但是要承担溢出的风险。

用杯子倒水已经不合适形容了,最方便的就是袋子中放西瓜。A袋子里有代号为a的西瓜,B袋子里有代号为b的西瓜,小笨球想让两个袋子的西瓜倒换,但是一次只能拿出一个西瓜(拿出来之后必须放在袋子里不能放在地上云云)。

那么就可以把a拿到B袋子中,然后B中就有ab两个西瓜。

再把B中的b放到A的袋子中,那么就倒换完毕。

import java.util.Scanner;
public class Main {

    public static void main(String[] args) {

        Scanner s = new Scanner(System.in);
        int num1 = s.nextInt(),num2 = s.nextInt();

        num1 += num2;
        num2 = num1 - num2;
        num1 = num1 - num2;

        System.out.println("num1 = " + num1 + 't' + "num2 = " + num2);
    }
}

 位异或法

位处理法是最棒的方法,既不需要开辟新的空间,又不会承担溢出的风险,唯一的缺点就是:不好理解。

先说说位异或,对位进行处理,同假异真。

位异或可以使得两个2进制串合并压缩成1个2进制串,然后用其中任意一个便可以求得另一个。

话句话说:

(a ^ b) ^ a == b;
(a ^ b) ^ b == a;

所以,交换两个数的时候只需要:

import java.util.Scanner;
public class Main {

    public static void main(String[] args) {

        Scanner s = new Scanner(System.in);
        int num1 = s.nextInt(),num2 = s.nextInt();

        num1 ^= num2;
        num2 ^= num1;
        num1 ^= num2;

        System.out.println("num1 = " + num1 + 't' + "num2 = " + num2);
    }
}
2014/12/13 16:28 下午 posted in  坏笔记不如好记性