西维蜀黍

【Golang】枚举(enumeration)

枚举(enumeration)

Golang 语言并没有提供enum的定义,我们可以使用const来模拟枚举类型。

type PolicyType int32

const (
    Policy_MIN      PolicyType = 0
    Policy_MAX      PolicyType = 1
    Policy_MID      PolicyType = 2
    Policy_AVG      PolicyType = 3
)

这里定义了一个新的类型PolicyType,并且定义了4个常量(Policy_MIN, Policy_MAX, Policy_MID, Policy_AVG),类型是PolicyType。

  ...


【Golang】变量访问域

变量修饰符(Access Modifier)

当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public 标识符。

如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected

Go 语言中变量的声明必须使用空格隔开,如:

var age int;
  ...


【Golang】map 基础

定义 map

可以使用内建函数 make 也可以使用 map 关键字来定义 Map:

/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type

/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)

如果不初始化 map,那么 map_variable 就是一个 nil。

nil map 不能写入键值对,但是可以读取内部的值(虽然这并没有任何意义,因为一定会得到已知的结果,即 value 为 0)。

package main

func main() {
	var a map[int]int
	println(a[22]) // Return 0

	a[1] = 33 // https://blog.golang.org/maps
}
  ...


【Golang】struct

structs

A struct is a sequence of named elements, called fields, each of which has a name and a type. Field names may be specified explicitly (IdentifierList) or implicitly (EmbeddedField). Within a struct, non-blank field names must be unique.

package main

import "fmt"

type Vertex struct {
	X int
	Y int
}

func main() {
	v := Vertex{1, 2}
	v.X = 4
	fmt.Println(v.X)
}
  ...


【Golang】interface 和 interface{} (empty interface)类型

interface

An interface type is defined as a set of method signatures.

A value of interface type can hold any value that implements those methods.

Interfaces in Go provide a way to specify the behavior of an object: if something can do this, then it can be used here. We’ve seen a couple of simple examples already; custom printers can be implemented by a String method while Fprintf can generate output to anything with a Write method. Interfaces with only one or two methods are common in Go code, and are usually given a name derived from the method, such as io.Writer for something that implements Write.

Note: There is an error in the example code on line a = v. Vertex (the value type) doesn’t implement Abser because the Abs method is defined only on *Vertex (the pointer type).

package main

import (
	"fmt"
	"math"
)

type Abser interface {
	Abs() float64
}

func main() {
	var a Abser
	f := MyFloat(-math.Sqrt2)
	v := Vertex{3, 4}

	a = f  // a MyFloat implements Abser
	a = &v // a *Vertex implements Abser

	// In the following line, v is a Vertex (not *Vertex)
	// and does NOT implement Abser.
	a = v

	fmt.Println(a.Abs())
}

type MyFloat float64

func (f MyFloat) Abs() float64 {
	if f < 0 {
		return float64(-f)
	}
	return float64(f)
}

type Vertex struct {
	X, Y float64
}

func (v *Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
  ...


【Golang】类型转换 - 类型断言(Type Assertion)和强制类型转换

类型断言(Type Assertion)

非安全的类型断言

package main

import "fmt"

func main() {
	var a interface{} = "ss"
	t := a.(string)
	fmt.Printf("%v", t)
}

在上面,我们将一个类型为 interface{} 的变量转换成了 string 类型。

我们可以使用类型断言(type assertion),以将一个类型为 interface{} 的变量,转换为基本数据类型或者复杂数据类型。

所谓”非安全“的类型断言,是指如果这个转换失败,则会直接在运行时报错:

package main

import "fmt"

func main() {
	var a interface{} ="ss"
	t:= a.(int)
	fmt.Printf("%d",t)

}

Error:

panic: interface conversion: interface {} is string, not int

goroutine 1 [running]:
main.main()
        /Working/GoPlayGround/main.go:7 +0x45

因此,就有了安全的类型断言。

安全的类型断言

package main

import "fmt"

func main() {
	var s interface{} = "BrainWu"
	if v, ok := s.(string); ok { // invalid type assertion: s.(string) (non-interface type string on left)
		fmt.Println(v)
	}
}

我们可以使用类型断言,将一个类型为 interface{} 的变量,转换为基本数据类型或者复杂数据类型

package main

import "fmt"

func main() {
	var a interface{} = 10
	t, ok := a.(int)
	if ok {
		fmt.Println("int", t)
	}
	t2, ok := a.(float32)
	if ok {
		fmt.Println("float32", t2)
	}
}

在进行安全的类型断言时,可以使用两个参数来接收返回值,其中第一个参数是转换成功后的值,一个是 bool,用于指示这次类型转换是否成功(如果转换失败,则 v 为期待转换类型的默认值),比如:

package main

import "fmt"

func main() {
	var s interface{} = "test"
	v1, ok := s.(int)
	if ok { // invalid type assertion: s.(string) (non-interface type string on left)
		fmt.Println(v1)
	}
	fmt.Println(v1)

	var s2 interface{} = 11
	v2, ok := s2.(AAA)
	if ok {
		fmt.Println(v2)
	}
	fmt.Println(v2)
}

type AAA struct {
	bb int
}

// output
0
{0}
  ...


【Hardware】ID 卡和 IC 卡

IC 卡

高频(High frequency)是指频带由3MHz到30MHz的无线电波,然而常用的RFID使用的高频频段为13.56MHz。

IC卡全称集成电路卡(Integrated Circuit Card),又称智能卡(Smart Card)。可读写,容量大,有加密功能,数据记录可靠,使用更方便,如一卡通系统,消费系统等,目前主要有PHILIPS的Mifare系列卡(也称为 M1 Card)。

类别

类型 频率 特性
Mifare S50(简称M1) 高频 最常见的卡,每张卡有独一无二的UID号,可保存修改数据,常见学生卡,饭卡,公交卡,门禁卡
Mifare UltraLight(简称M0) 高频 低成本卡,出厂固化UID,可储存修改数据,常见地铁卡,公交卡
Mifare UID(简称UID卡) 高频 M1卡的变异版本,可修改UID,国外叫做中国魔术卡,可以用来克隆M1 S50的数据

HID

  • iCLASS® Seos
  • iCLASS SE®
  • iCLASS®
  • Crescendo®
  • HID Proximity

MIFARE Classic 1K(简称 M1 卡)

目前最常见的高频卡,也是我们口中俗称的IC卡。

M1卡可储存的数据大小为1K,分为16个扇区(sector),每个扇区分4个块(block),每个块为16个字节,以块为存取单位。每个扇区都有独立的一组密码(key A and key B)及访问控制

每张卡有唯一的一个32位的序列号。每个扇区的第0、1、2块为可用数据区,用来存储数据,第3块为控制块,包括了密码A(key A)、存取控制(Access Bits)、密码B(key B)。

每张卡的第0扇区的第0块用来存放厂商代码(Manufacturer data, including UID),contains the UID, BCC, SAK, ATQA and Manufacturer data,在通常情况下,不可更改。

中间4字节控制字是管理密码权限,用来设置A密码和B密码的功能。默认不修改的时候,可以用A密码读写所有数据。A密码不可读出,B密码可以用A密码读出。密码不一定可以读取,由控制字决定。

M1 UID卡/普通复制卡

M1 UID卡是针对M1 S50卡特制的变种卡,用起来和M1 S50完全一样,只是多了一个功能,可以重复擦写所有扇区,包括0扇区块。因此UID号也可以随意修改,厂家信息也可以随意修改。

CUID卡/升级复制卡

CUID卡是针对FUID卡做的优化。CUID卡可以重复修改0块,但是它和UID卡的区别是,UID卡是通过指令修改0块,CUID使用的是常规密码验证的方法写0块,其他扇区和标准M1卡相同。缺点是,有可能会被检测出来,而且如果不小心写错了UID号的校验位导致无法读卡,没办法修复只能报废。

FUID卡/高级复制卡

FUID卡是针对UID卡做的优化。新的读卡系统,通过检测卡片对特殊指令的回应,可以检测出UID卡,因此可以来拒绝UID卡的访问,来达到屏蔽复制卡的功能。

FUID的0扇区可以被修改,但只可以修改一次,写错也没办法更改,因而不能重复利用。

但是修改后和M1卡完全一样,很难被屏蔽检测。

UFUID卡/高级复制卡 - 推荐

就是UID和FUID的合成卡,需要封卡操作时,封卡之后变成M1卡,不封卡时就是UID卡。

破解

arc122u只能读取和修改高频卡(IC 卡),有点不足

ID卡

ID卡全称身份识别卡(Identification Card),是一种不可写入的感应卡,含固定的编号,主要有台湾SYRIS的EM格式,美国的HID、TI 和 MOTOROLA等各类ID卡。

ID卡属于大家常说的低频卡,一般大部分情况下作为门禁卡或者大部分大学里使用的饭卡,一般为厚一些的卡,是只读的,卡里面只保存有一串唯一的数字序号ID,可以把这串数字理解为你的身份证号,刷卡的时候,读卡器只能读到ID号,然后通过跟后台数据库进行匹配,如果是门禁卡,那么数据库里面就是存在这样的ID号,如果匹配上门就开了,匹配不上门就开不了。

如果是学校的饭卡,刷卡的时候,实际上操作的是你对应ID号相关的数据库中的数据。ID卡本身不存在任何其他数据,所以,学校使用的ID卡饭卡,只能复制卡,刷别人的钱(数据库中的钱),再没有其他办法。

如果卡上写着 HID,这张卡也可能是 IC 卡(see https://www.hidglobal.com/product-display/cards-and-credentials/iclass)。

由此可以看出,ID卡是可加密的存储卡、ID卡是只读的低频卡。

CPU卡

CPU card chip is a microprocessor, If you want to achieve more advanced features and the security level is particularly high, its function is equivalent to a microcomputer. CPU cards can be applied to many fields such as finance, insurance, traffic police, and government industries etc.

有操作系统,可存储数据,也有自己的ID号,CPU卡发一串数据给设备,设备与SAM卡进行运算,设备再发一串数据回CPU卡确认,然后进行交易或身份认证;跟M1卡的区别在于一个算法在空中,一个算法在设备里面;无论是卡商,设备商,运营商,都不知道其中的算法,所以这个系统的安全性会高很多。

  ...


【MySQL】数据类型(Data Types)

数字类型 (Numeric Data Types)

Integer Type (Exact Value)

Difference is in range and storage. Choose unsigned to maximise the maximum value if not using negative values.

  • TINYINT:一个微小整数,支持 -128到127(SIGNED),0到255(UNSIGNED),需要1个字节存储
  • SMALLINT:一个小整数,支持 -32768到32767(SIGNED),0到65535(UNSIGNED),需要2个字节存储
  • MEDIUMINT:一个中等整数,支持 -8388608到8388607(SIGNED),0到16777215(UNSIGNED),需要3个字节存储
  • INT:一个整数,支持 -2147493648到2147493647(SIGNED),0到4294967295(UNSIGNED),需要4个字节存储
  • INTEGER:同INT
  • BIGINT:一个大整数,支持 -9223372036854775808到9223372036854775807(SIGNED),0到18446744073709551615(UNSIGNED),需要8个字节存储

注意,默认为SIGNED,只有显式地声明为UNSIGNED,才是UNSIGNED。

Type Storage (Bytes) Minimum Value Signed Minimum Value Unsigned Maximum Value Signed Maximum Value Unsigned
TINYINT 1 -128 0 127 255
SMALLINT 2 -32768 0 32767 65535
MEDIUMINT 3 -8388608 0 8388607 16777215
INT 4 -2147483648 0 2147483647 4294967295
BIGINT 8 -2$^{63}$ 0 2$^{63}$-1 2$^{64}$-1

See https://dev.mysql.com/doc/refman/5.6/en/integer-types.html for more details.

  ...


【MySQL】MySQL 中的各种数据类型转换

Int -> varcher

将Int 转为varchar可以用 concat() 函数,比如 concat(8,’0′) 得到字符串 ’80′。

delete from core_channel;


drop procedure if exists insert_channel;

delimiter //

CREATE procedure insert_channel()
wholeblock:BEGIN
  declare str VARCHAR(255) default '';
  declare x INT default 0;
  SET x = 1;

  WHILE x <= 10 DO
    insert into core_channel (name) values (CONCAT("name",x));
    SET x = x + 1;
  END WHILE;

  select str;
END//

call insert_channel	();
  ...


【Golang】Golang 命令

Golang 命令

$ go
Go is a tool for managing Go source code.

Usage:

	go <command> [arguments]

The commands are:

	bug         start a bug report
	build       compile packages and dependencies
	clean       remove object files and cached files
	doc         show documentation for package or symbol
	env         print Go environment information
	fix         update packages to use new APIs
	fmt         gofmt (reformat) package sources
	generate    generate Go files by processing source
	get         add dependencies to current module and install them
	install     compile and install packages and dependencies
	list        list packages or modules
	mod         module maintenance
	run         compile and run Go program
	test        test packages
	tool        run specified go tool
	version     print Go version
	vet         report likely mistakes in packages

Use "go help <command>" for more information about a command.

Additional help topics:

	buildmode   build modes
	c           calling between Go and C
	cache       build and test caching
	environment environment variables
	filetype    file types
	go.mod      the go.mod file
	gopath      GOPATH environment variable
	gopath-get  legacy GOPATH go get
	goproxy     module proxy protocol
	importpath  import path syntax
	modules     modules, module versions, and more
	module-get  module-aware go get
	module-auth module authentication using go.sum
	module-private module configuration for non-public modules
	packages    package lists and patterns
	testflag    testing flags
	testfunc    testing functions

Use "go help <topic>" for more information about that topic.
  ...