随机数定义

根据密码学原理,随机数的随机性检验可以分为三个标准:

1.统计学伪随机性。
	统计学伪随机性指的是在给定的随机比特流样本中,1的数量大致等于0的数量,同理,“10”“01”“00”“11”四者数量大致相等。
	类似的标准被称为统计学随机性。满足这类要求的数字在人类“一眼看上去”是随机的。
2.密码学安全伪随机性。
	其定义为,给定随机样本的一部分和随机算法,不能有效的演算出随机样本的剩余部分。
3.真随机性。
	其定义为随机样本不可重现。实际上只要给定边界条件,真随机数并不存在。
	可是如果产生一个真随机数样本的边界条件十分复杂且难以捕捉(比如计算机当地的本底辐射波动值),可以认为用这个方法演算出来了真随机数。

相应的,随机数也分为三类:

  • 伪随机数:满足第一个条件的随机数。
  • 密码学安全的伪随机数:同时满足前两个条件的随机数。可以通过密码学安全伪随机数生成器计算得出。
  • 真随机数:同时满足三个条件的随机数。

生成伪随机数算法

伪随机数生成算法,也叫伪随机数生成器(Pseudo Random Number Generator,简称 PRNG)1
伪随机数序列,其实是确定的,只是看上去随机。比如在线性同余法中,当第一数确定后, 后续的值也就确定了。
生成n个随机数 \( x_1, x_2, …, x_n \)

可以使用一个 4 元组\( (Q, \sigma, \Sigma, f)\) 定义一个伪随机数生成算法, 其中:

  • \( Q 是有限状态集合, \)
  • \(\sigma\) 为状态转移函数,
  • \(\Sigma\) 是有限输出集合,
  • \(f 是从 Q 到 \Sigma 的单射。\)

当需要一个伪随机数序列时,设定初始状态 \( q_0 \in Q \) ,每一次输出都由如下两个过程组成

  • \( q_{n} = \sigma(q_{n-1}) \)
  • \( output_n = f(q_n), output_n \in \Sigma \)

Linear congruential generator(线性同余法)

  1. a是乘数,b为增量,m为模数,\(x_0\)是种子数
  2. 一般而言,m是2的高次冪(\(2^{32}或2^{64}\)), \(0<a<m,0<=b<m,0<x_0<m\)
  3. 一般选取:\( a=4p+1, b=2q+1,其中p,q是正整数 \) 2
  4. m越大,序列的周期越长, a和b越大产生的伪随机数越均匀
  5. a和m互质,产生的随机数效果比不互质好
  6. LCG不能用于随机数要求高的场合,不能用于加密应用。
  7. 有些场合LCG有很好的应用,例如内存很紧张的嵌入式中,电子游戏控制台用的小整数,使用高位可以胜任。
rand = 1
def Lcg():
	a = 69069
	b = 1
	m = 1<<22
	global rand
	rand = (a * rand + b) %m
	return rand

	

平法取中法

1964年由冯.诺依曼提出。基本思路:将数列中\(x_i\)(假设有m位)平方,取得到2m位数(不足2m位,在最高位前面补0) 取正中间m位数字,作为\(x_{i+1}\),由此产生一个伪随即数列。

rand = 1
def middle_square():
	global rand
	m = 16
	rand = rand ** 2
	rand = (rand // 10**8) % 10**8
	return rand

Blum Blum Shub(BBS生成器)

Mersenne twister(梅森旋转算法)

参考资料

  1. https://zhuanlan.zhihu.com/p/33903430 

  2. https://www.cnblogs.com/forget406/p/5294143.html 

窗口(window)和分区span快速切换

bind-key num
在配置文件中加入`bind-key C-w last-window`就可以通过bind-key Ctrl+w来切换上次和当前的window了

`bind-key C-a last-span`,就可以通过bind-key Ctrl+a来切换上次和和当前的span

导出一些数据给运营同学

几点要求

  • 一个脚本搞定,尽可能少地依赖其他包
  • 可以用windows下的excel打开,中文不乱码
  • 可以是csv文件,也可以用\t分割,生成xls文件

excel的坑

在程序中能够正常输出中文,但是导出到文件后使用excel打开是出现中文乱码 因为excel能够正确识别用gb2312、gbk、gb18030或utf_8 with BOM 编码的中文, 如果是utf_8 no BOM编码的中文文件,excel打开会乱码。


代码如下:

#!/usr/bin/python3
#coding:utf-8
import pymysql
import json

try:
    db = pymysql.connect("localhost","usrname","password","dbname",4040)
    cursor = db.cursor()
    sql = "select org_code,command_return from upgrade_log where upgrade_id=1060 and stage_id=68"
    cursor.execute(sql)
    # 关键是设置encoding="utf_8_sig",这样excel打开才不会出现中文乱码
    # 这样生成的文件就是有BOM头,excel才能正常处理中文
    fh = open("400.csv","w",encoding="utf_8_sig") 
    for row in cursor:
        org_code = row[0]
        info =json.loads(row[1]) # row[1]是一段json
        if len(info[2:]) > 0:
            for item in info[2:]:
                line = item.replace("\t",',')
                if line[-4:] != "NULL":
                    line = line+", "
                line = org_code+","+line +"\n"
                fh.write(line)
        else:
            print(org_code)

        
except Exception as err:
    print(err)

fh.close()
cursor.close()
db.close()

Basic types

  • 布尔(bool) 默认值false
  • 字符串(string) 默认值””
  • 数字类型
    • int int8 int16 int32 int64 有符号整数 默认值0 int(-128,127)
    • uint uint8 uint16 uint32 uint64 uintptr 无符号整数 uint(0,255)
    • byte // int8的别名
    • rune // int32的别名,代表unicode值
    • float32 float64 默认值0 浮点数
    • complex64(32位实数和32位虚数) complex128(64位实数和64位虚数)
  • 派生类型
    • 指针类型(pointer) 默认值是nil
    • 数组类型
    • 结构化类型(struct)
    • channel类型
    • 函数类型
    • 切片类型
    • 接口类型(interface)
    • Map类型

类型转换

  • T(v) 显示类型转换,如int(12.4),string(11244)
    • 不过整型转为string是按照ascii码或unicode码转为对应的字符,所以有可能得到乱码
原类型\转化后 bool int float string complex
bool 1 0 0 0 0
int 0 1 1 1 0
float 0 1 1 0 0
string 0 0 0 1 0
complex 0 0 0 0 1

Variables with initializers(变量和初始化)

// 再函数内部以下三种写法都一样
var i,j int = 1, 3  // 全局可以用
var i, j = 1,3     // 全局可以用
i,j := 1,3 // 只能在函数体内部使用

Constants常量

1.定义格式

const Varname [type] = value

2.其他说明

  1. 常量的值可以是内置函数的返回值,const LEN int = len("asdf")
  2. 多个常量(常量组)
    const (
         a = "abc"
         b = len(a)
         c = b + b*b
         d     // 常量组,如果不提供初始化值,则表示用上一行的表达式的值,所以d 为12
         e  // 同上e 为12
       )
    

运算符

1. 关系运算符: == != > < >= <= 
2. 逻辑运算符: &&  ||  ! 
3. 位运算(都是双目): & | ^(按位异或) << >>
4. 赋值运算符: 
	 = += -= *= /= %= <<= >>=
	 &= ^= |=( c|=2等于 c = c|1)

5. 指针相关的运算符(单目): &(取地址符) *(获取指针的值)
	var ptr *int // 定义一个指向整型的指针变量
	a := 123
	ptr = &a // 获取变量a的地址,赋值给指针变量ptr
	val = *ptr // 获取指针ptr指向的值

条件语句

1. if 
  if a > 1 {
	fmt.Println("big")
  }
2. if else
 if a > 1 {
	fmt.Println("big")
 }else {
	fmt.Println("small")
 }

3. swith case 终于去到了其他编程语言的break;
 switch variable {  
	 case val1:
		 Println("var1")
	 case val2:
		 Println("var1")
	 case val4,val5,varl6:  // 符合多个变量
		 Println("var456")
			 ...
	 default:
		Println("default")

 }
a. 变量var可以是任何类型的而val1和val2必须时var同类型的任意值或者是最终结果是var同类型的表达式
b. 一般情况下只会执行一个case 

4. select

select是Go中的一个控制结构类似于用于通信的switch语句每个case必须是一个通信操作要么是发送要么是接收

select随机执行一个可运行的case如果没有case可运行它将阻塞直到有case可运行
一个默认的子句应该总是可运行的

 var c1, c2, c3 chan int
   var i1, i2 int
   select {
      case i1 = <-c1:
         fmt.Printf("received ", i1, " from c1\n")
      case c2 <- i2:
         fmt.Printf("sent ", i2, " to c2\n")
      case i3, ok := (<-c3):  // same as: i3, ok := <-c3
         if ok {
            fmt.Printf("received ", i3, " from c3\n")
         } else {
            fmt.Printf("c3 is closed\n")
         }
      default:
         fmt.Printf("no communication\n")
   }    


循环结构


1. for

var b int = 15
   var a int

   numbers := [6]int{1, 2, 3, 5} 

   /* for 循环 */
   for a := 0; a < 10; a++ {
      fmt.Printf("a 的值为: %d\n", a)
	  if a == 7 {
		continue	
	  }
	  if a == 9 {
		break
      }		
   }

   for a < b {
      a++
      fmt.Printf("a 的值为: %d\n", a)
   }
   
	/*
	* label: statement
    * goto label
	*/
   DEBUG1:for i,x:= range numbers {
	  if i == 4 {
		goto DEBUG1   // goto的使用
	  }	
      fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
   }   

函数

格式: func function_name([parameter list]) [return_types] { … }

变量作用域

  • 函数体内部定义的变量(局部变量),只在函数体内部有用
  • 函数外部定义的变量(全局变量),可以在整个包甚至外部包(被导出后)使用
  • 函数定义中的变量(形式参数,也是局部变量)
  • 当局部变量与全局变量的名称相同时,局部变量优先使用
func main() {
	var a int = 0
	Println(a) // 0 
	// 在for循环的initialize中(a:=0),此时for循环的a 和局部变量a不是同一个变量。initialize的a是for循环的局部变量,for循环结束后,就不能访问了。
	for a:=0; a < 10; a++ {
		Println(a) // 0,1,2,...,9
	}
	Println(a) // 0
}

数组

数组的大小在定义之后就固定了,所以在golang代码中,数组用得不是很多,而切片(可以简单理解为长度可变的数组)用得很多

  • 数组申明: var variable [SIZE] variable_type var arr [10] int var variable_name [SIZE1][SIZE2]…[SIZEN] variable_type //多维数组 var thread [5][10][2] int // 定义一个三维数组

  • 数组初始化 var balance = [5]int{1,3,3,4} // 初始化一个数组,长度为5,元素是1,3,3,4 var balance = […]int{1,3,3,4} // 初始化一个数组,可以不指定数组大小 var balance = [2][2]int{ {1,3}, {3,5}, // 这行尾里要有逗号 }

  • 访问数组元素 通过索引访问,索引从0开始 var salary int = balance[1] // 获取第二个元素 3
      var arr = [5]int{1, 3, 4, 5}
      // 遍历数组1
      for i := 0; i < 5; i++ {
          fmt.Printf("arr[%d]= %d\n", i, arr[i])
      }
      // 遍历数组2
      for k, v := range arr {
          fmt.Printf("arr[%d]= %d\n", k, v)
      }	
    
  • 向函数传递数组

    void myFunc(arr [10]int) // 指定了数组的大小,该函数只能接受指定长度的数组 { … }

    void myFunc1(arr []int) // 不指定数组的大小,该函数只能接受不定长度的数组 { … }

指针

取地址符&,返回一个变量的内存地址

var a int = 10
fmt.Printf("a的内存地址:%x\n",&a)  // 输出十六进制 c00006e060
  • 指针变量

    变量的内存地址(一个整数而已),也可以保存在其他变量中,这种变量就是指针变量 虽然它存储的其实就是一个整数,但是定义的格式不能按照整型变量来。

    定义指针变量 var var_name *var_type

    var ip *int // 这个指针变量ip,只能用它来存放一个整型变量的地址 var fp *float32 // fp可以存放一个float32类型变量的地址

    指针变量赋值 var a int = 10 var ptr *int ptr = &a //ip的值就是变量a的内存地址

    获取指针变量指向的内容 *ptr //就可以取出变量a的值,及10

    空指针(申明了,但是不赋值的指针变量,它的值就不是大于零的整数(内存地址),而是nil) if ptr != nil // 不是空指针 if ptr == nil // 空指针 ,fmt.Printf(“%x\n”,ptr),输出是0

    指针数组 const MAX int = 3 var ptr [MAX]*int //定义一个长度为3的数组,数组的元素是指向整型的指针

    指针变量作为函数的参数 func swap(a int ,b *int) { // a和b都是指针变量 *a,b = b ,a }

    指针的指针 var a int = 12 var p *int var ptr **int p = &a ptr = &p //ptr的值是一个内存地址,这个地址指向变量p,而变量p又是一个指向整数的指针,

结构体

  • 定义: // 定义后的结构体就可以当作类型,用来申明变量了。 type struct_var_type struct { member definition; member definition; … member definition; }

    type Book struct { title string author string }

  • 定义结构体类型的变量 var_name := struct_type {v1,v2,…,vn} var_name := struct_type {k:v1,k2:v2,…,kn:vn}

    1. var cbook Book cbook = Book{“c”,”ken”}

    1. gobook := Book{“golang”,”poke”}
  • 访问结构体成员: struct_val.member

  • 结构体指针 var struct_pointer *Books //定义一个指向Books结构体变量的指针 struct_pointer = &Book1; 结构体指针可以访问结构体成员 struct_pointer.title; // 等同与 Book1.title

Slice切片

** A slice is a descriptor of an array segment. It consists of a pointer to the array, the length of the segment, and its capacity (the maximum length of the segment). **

slice是对数组的抽象。数组的长度固定,有时不发方便使用。切片的长度不固定([]中没内容),可以追加元素,容量增大
An array variable denotes the entire array; it is not a pointer to the first array element (as would be the case in C).

  • 定义和初始化

    letters := []string{‘a’,’b’,’c’} // 定义一个切片,注意中括号中没内容 letters2 := [10]string{‘a’,’b’,’c’} // 定义一个数组,注意中括号中有整数 letters3 := […]string{‘a’,’b’,’c’} // 定义一个数组,注意中括号中有…

    var identifier []type //声明一个切片,没有指定大小,此时值为nil var identifier []type = make([]type,len) // 声明一个切片,指定大小 identifier := make([]type,len) // 同上 identifier := make([]type,len,capacity) // 声明一个切片,长度len,容量capacity

    //直接初始化 identifier := []int{1,3,5} // 初始化一个切片,[]int表示切片的类型,{1,2,3}是初始化的值

    //用数组初始化切片 identifier :=arr[start:end] // 用数组从下标start到end-1的元素创建一个slice

    s1 := arr[start:] // 从下标start到最后 s1 := arr[:end] // 下标从0开始到end-1的元素 s1 := arr[:] // 所有的元素

    var s2 = make([]int,3,5) // s2的值,{0,0,0} var s3 []int // s3 == nil

    len切片<=cap切片<=len数组

  • 切片截取 和数组截取一样 s4 := s2[1,3] // {0,0}

  • 切片append()&copy() s := []int{1,3,4,5} s = append(s,6) // s变为1,3,4,5,6 s = append(s,7,8) // s变为1,3,4,5,6,7,8

    s2 := make([]int,len(s),cap(s)*2) copy(s2,s) // 把s的内容复制到s1

  • 切片作为函数参数(其实是引用传参)

    func deal(x []int) { x[0] = 66 }

    func main() { a := make([]int,5) // 创建一个切片 fmt.Println(a) // [0,0,0,0,0] deal(a) // 实际a就是一个引用传参,不是传值。这点和数组不同。 fmt.Println(a) // [1,0,0,0,0] }

Range

range关键字用于for循环中 迭代数组,切片,通道或集合或字符串的元素。在array和slice中返回元素的索引和对应的值

for i,v := range arr{
	...
}

for _,v := range slie {
	...
}

for k :=range map {
	Println("key=",k,"value=",map[k])
}

map

  • 定义Map var identifier map[key_type]val_type // var my_map map[string]int map_var = make(map[key_type]val_type) // info = make(map[string]int)

    如果不初始化,就是一个nil map

    my_map[“name”] = “shangsna” my_map := map[string]string{“name”:”lisi”,”hobby”:”reading”}

    name,err = my_map[“name”] if err == nil { 存在该key }else { 不存在该key }

Interface

Interface(接口),把所有共性的方法定义在一起,其他类型只要实现了这些方法就是实现了这个接口

type interface_name interface {
	method1 [return_type] // 返回值可以没有
	method2 (int,int)
	...
	methodn string
}
	
定义结构体
type struct_name struct {
	// variables
}

用这个结构体去实现这个接口
func (st1 struct_name) method1()[return_type] {
	//实现这个方法
	...
}
...
func (stn struct_name) methodn()[return_type] {
	//实现这个方法
	...
}

/*定义一个Phone接口*/
type Phone interface {
	call() int  //返回值是整型
	camera(int) (int, string) // 返回值有两个
}

/**定义一个Huawei结构体**/
type Huawei struct {
	name string
}

/* 用Huawei结构体,实现了一个call()方法
func (matex Huawei) call() int {
	fmt.Println("matex belint the world")
	return 0
}

/* 实现一个camera()方法 */
func (matex Huawei) camera(px int) (int, string) {
	fmt.Println("take great pic",px ,"px")
	return 0, "huawei"
}

可能是最适合开发的数据库客户端

支持的数据库类型:

SAP Sybase SQL Anywhere (SA/ASA)
SAP Sybase IQ
SAP Sybase Adaptive Server Enterprise (ASE)
SAP HANA
SAP Sybase UltraLite (UL)
Oracle
Oracle RDB
SQL Server
MySQL
PostgreSQL
DB2
Firebird
Ingres
Interbase
SQLite

本文以MySQL为例,介绍一下该插件的功能。

安装&配置

Lets test the connection, run the following command (Note the capital S): >
`:Select * from customer`
Select, Update, Insert, Delete, Call, Drop, Alter, Create

功能介绍

connect

使用快捷键 :`<leader>sbp` leader键默认是`\`,  sbp(sql buffer prompt)
使用ex命令:`:DBPromptForBufferParameters`
然后选择要连接的数据库类型

execute

把光标置于sql语句中的任意位置(sql语句是一行)
`<leader>sel`  sql execute line

执行多行sql
`<leader>se`  sql execute 
`:DBExecSQLUnderCursor`

执行选中的sql
`:DBExecVisualSQL`
<leader>se  和多行执行一样

从表中查选,光标在表名称的单词上
`<leader>st`  sql table
`:DBSelectFromTable`
执行的sql是:select * from table_name

带条件的查询
`<leader>stw`
`:DBSelectFromTableWithWhere`
会提示你输入where条件, 比如 id > 1 and name like "zhangsan"
执行的sql:select * from table_name where id > 1 and name like "zhangsan"

等待输入表名查询
`<leader>sta`
`:DBSelectFromTableAskName`
会提示你输入你要查询的表名

高亮选择表名查询
`<leader>st`
`:'<,'>DBSelectFromTable`

Describing objects

表结构
`:DBDescribeTable`
`\sdt` sql describe table

存储过程procedures
`:DBDescribeProcedure`
`\dp`  d (describe) p (procedure)