西维蜀黍

【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.

  ...