tonglin0325的个人主页

常用哈希、加密算法

下面列举了一些常用的加密算法

加密算法 类别 介绍 安全性
MD5 hash函数 MD5一种被广泛使用的密码散列函数,可以产生出一个128位(16个字节)的散列值(hash value)。MD5是输入不定长度信息,输出固定长度128-bits的算法。 不安全
base64 编码 Base64就是一种基于64个可打印字符来表示二进制数据的方法。Base64会增加原文的长度,通常是原始长度的 4/3 -
SHA-1 hash函数 Secure Hash Algorithm 1(SHA-1)安全散列算法1是一种密码散列函数。SHA-1结果的长度:160 位(20 字节) 不安全
SHA-256 hash函数 SHA-256是一种加密哈希函数,可生成固定大小的256 位(32 字节)哈希值,其广泛用于数据完整性校验 安全
SHA-384/512 hash函数 SHA-384是SHA系列中的另一种算法,它产生的哈希值为96个字符长度的十六进制数字。 与SHA256相比,SHA384具有更强的安全性。 由于其输出长度更长,因此在实际应用中适用于更高的安全需求 安全
Hmac 消息认证码 HMAC(Hash-based Message Authentication Code)是一种基于哈希函数的消息认证码,用于验证消息的完整性和真实性。它结合了一个加密密钥和哈希函数,为消息提供更高的安全性。它要求通信双方共享密钥、约定算法、对报文进行Hash运算,形成固定长度的认证码。 Hmac算法可以用来作加密、数字签名、报文验证等。 HMAC 的安全性依赖于所使用的哈希函数的强度
DES 对称加密算法 DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法。DES算法的入口参数有三个:Key、Data、Mode。其中Key为DES算法的秘钥,长度8个字节(64位),其中有56位用于实际加密,还有8位用于奇偶校验;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。 不安全
3DES 对称加密算法 3DES(即Triple DES)是DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。 较安全
AES 对称加密算法 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard)。支持128位,192位和256位的秘钥长度,是目前最流行的对称加密算法。 安全
RSA 非对称加密算法 RSA算法是一种非对称加密算法,与对称加密算法不同的是,RSA算法有两个不同的密钥,一个是公钥,一个是私钥。RSA允许选择公钥的大小。512位的密钥被视为不安全的;768位的密钥不用担心受到除了国家安全管理(NSA)外的其他事物的危害。RSA 加密的密文长度等于密钥的长度(以字节为单位)。常见密钥长度包括 1024 位、2048 位、3072 位等。场景:在需要保护数据机密性的场景中,RSA可以用于对敏感数据进行加密。使用公钥加密,私钥解密。适合对小数据量的内容加密(如密钥、凭据等),但不适合大数据量加密(因为效率较低)。 安全
DSA 非对称加密算法 DSA(Digital Signature Algorithm)是一种用于生成和验证数字签名的算法,主要用于确保数据的完整性和发送者身份的真实性。DSA 专用于生成和验证数字签名,不能用于加密数据。安全性依赖于密钥长度以及散列函数的选择。 安全
ECC 非对称加密算法 ECC(Elliptic Curve Cryptography)是一种基于椭圆曲线数学的公钥加密算法。它是一种非对称加密技术,因其提供高安全性和较小的密钥长度,已成为现代加密的主流技术之一。ECC 广泛应用于数字签名、密钥交换和加密等领域。相较于 RSA 和 DSA,ECC 在提供相同安全性的情况下,使用更短的密钥,计算量更小。ECC 适合资源有限的设备,如嵌入式系统、物联网设备和移动设备。 安全
Blowfish 对称加密算法 Blowfish 是一种对称加密算法,由 Bruce Schneier 在 1993 年设计。它被广泛使用于加密数据的保护,特别是应用于资源受限的环境(如嵌入式系统)。Blowfish 是一种分组加密算法,因其高效性和灵活性,成为了当时替代传统算法(如 DES)的重要选择。 安全
RC4 对称加密算法 RC4(Rivest Cipher 4)是一种对称流加密算法,由 Ron Rivest 于 1987 年设计。这种算法因其简单、高效的特性,曾被广泛应用于通信加密、文件加密以及各种加密协议中(如 SSL/TLS 和 WEP)。然而,由于其已被证明存在严重的安全漏洞,RC4 在许多场景下已不再推荐使用。 不安全

MySQL学习笔记——函数

MySQL函数官方文档可以参考:https://dev.mysql.com/doc/refman/5.7/en/functions.html

1.内置函数和运算符

参考:https://dev.mysql.com/doc/refman/5.7/en/built-in-function-reference.html

1.常用函数

5.流程控制函数

参考:https://dev.mysql.com/doc/refman/5.7/en/flow-control-functions.html

CASE函数

1
2
3
4
5
6
7
8
# 条件判断语句
SELECT NAME,sex,age '原来年龄'
CASE
WHEN age IS NULL THEN 100
ELSE age
END AS '年龄'
FROM tb_emp;

IF()函数

1
2
3
4
5
6
7
8
# IF(expr1,expr2,expr3),如果expr1是True,返回expr2,否则返回expr3
mysql> SELECT IF(1>2,2,3);
-> 3
mysql> SELECT IF(1<2,'yes','no');
-> 'yes'
mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
-> 'no'

IFNULL()函数

1
2
3
4
5
6
7
8
9
10
# IFNULL(expr1,expr2),如果字expr1不为NULL,则返回expr1,如果为NULL,则返回expr2 
mysql> SELECT IFNULL(1,0);
-> 1
mysql> SELECT IFNULL(NULL,10);
-> 10
mysql> SELECT IFNULL(1/0,10);
-> 10
mysql> SELECT IFNULL(1/0,'yes');
-> 'yes'

NULLIF()函数

全文 >>

MySQL学习笔记——增删改查

有关数据库的DML操作

  -insert into

  -delete、truncate

  -update

  -select

    -条件查询

    -查询排序

    -聚合函数

    -分组查询

 

DROP、TRUNCATE、DELETE

-DELETE删除数据,保留表结构,可以回滚,如果数据量大,很慢,回滚就是因为备份删除的数据

-TRUNCATE删除所有数据,保留表结构,不可以回滚,一次全部删除所有数据,速度相对很快

-DROP删除数据和表结构,删除数据最快(直接从内存抹去这一块数据)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#1.指明字段进行插入,注意字段和值的数量和类型都需要匹配
INSERT INTO tb_dept (NAME,loc,description) VALUES('开发部','广州','负责软件开发工作');

#2.如果插入的values是所有字段,可以不同显式写插入的字段名,不推荐
INSERT INTO tb_dept VALUES(3,'财务部','广州','负责财务工作');

#auto_increment会记住曾经生成的值

#3.一次插入多条记录 mysql特有
INSERT INTO tb_dept (NAME,loc,description)
VALUES('开发部','广州','负责软件开发工作'),
('财务部','广州','负责财务工作'),
('市场部','广州','负责采购工作');

#4.可以从一张表中插入数据
#创建一张表和tb_dept表的结构一样,通过这种方式建表只是复制表结构,不复制约束
CREATE TABLE tb_dept2
SELECT * FROM tb_dept
#where id = 99

#先建表再插入
INSERT INTO tb_dept2(id,NAME,loc,description)
SELECT id,NAME,loc,description FROM tb_dept

INSERT INTO tb_emp(id,NAME,sex,age,address,email,dept_id)
VALUES(1,'Tony','男',26,'广州','Tony@163.com',1);

#更新 UPDATE table SET column = value [,column = value] [WHERE condition]
#where建议使用主键或者唯一键,建议是主键
UPDATE tb_emp SET age=23 WHERE id = 1;
UPDATE tb_emp SET age=23,sex='女' WHERE id = 2;

#删除 DELETE [FROM] table [WHERE condition];
DELETE FROM tb_emp; #删除表所有数据
DELETE FROM tb_emp WHERE id=2;

#阶段,DDL语句 TRUNCATE语句 作用是完全清空一个表
TRUNCATE TABLE tb_emp;

 

最简单的SELECT语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#查找 字段、字段。。。从 表 *表示所有的列
SELECT NAME,loc,description FROM tb_dept
SELECT * FROM tb_dept
SELECT NAME FROM tb_dept

#SELECT语句中的算数表达式
SELECT NAME,age,age*2
FROM tb_emp;

#NULL和0还有空字符不是一个概念
SELECT * FROM tb_emp;
SELECT * FROM tb_emp WHERE age = 0;
SELECT * FROM tb_emp WHERE age IS NULL;

#改变列的标题头,别名
SELECT NAME '姓名',age AS '年龄',age*2 '年龄乘2'
FROM tb_emp;

#重复记录
#缺省情况下查询显示所有行,包括重复行
SELECT dept_id
FROM tb_emp;

#使用DISTINCT关键字可从查询结果中清楚重复行
SELECT DISTINCT dept_id
FROM tb_emp;

#DISTINCT作用的范围是后面字段的组合
SELECT DISTINCT dept_id,age
FROM tb_emp WHERE dept_id=1;

#使用WHERE子句限定返回的记录
SELECT *
FROM tb_emp
WHERE age=22;

#字符串和日期要用单引号括起来
SELECT *
FROM tb_emp
WHERE NAME = 'Tom';

#比较运算符> < >= <= = <>
SELECT NAME,age
FROM tb_emp
WHERE age>=24;

SELECT NAME,age
FROM tb_emp
WHERE age>=24 AND age<27;

#BETWEEN AND 包含最小值和最大值
SELECT NAME,age
FROM tb_emp
WHERE age BETWEEN 24 AND 27;

#使用IN运算符
SELECT NAME,age
FROM tb_emp
WHERE age IN (22,26);

SELECT NAME,age
FROM tb_emp
WHERE age NOT IN (22,26);

#使用LIKE运算符进行模糊查询 _代表一个字符 %代表一个或者多个字符
SELECT NAME
FROM tb_emp
WHERE NAME LIKE '_a%';

#IS NULL
SELECT NAME,age
FROM tb_emp
WHERE age IS NULL;

#对结果进行排序 ORDER BY 从高到低
SELECT *
FROM tb_emp
ORDER BY age DESC;

#默认从低到高或者ASC
SELECT *
FROM tb_emp
ORDER BY age;

 

MySQL学习笔记——约束

1.数据库约束简介

1.约束是在表上强制执行的数据检验规则,约束主要用于保证数据库的完整性。

2.当表中数据有相互依赖性时,可以保护相关的数据不被删除。

3.大部分数据库支持下面五类完整性约束:

  - NOT NULL非空

  - UNIQUE Key唯一值

  - PRIMARY KEY主键

  - FOREIGN KEY外键

  - CHECK检查

4.约束作为数据库对象,存放在系统表中,也有自己的名字

5.创建约束的时机:

  -在建表的同时创建

  -建表后创建(修改表)

6.有单列约束和多列约束

2.列级约束和表级约束

列级约束直接跟在列后面定义,不再需要指定列名,与列定义之间用空格分开

表级约束通常放在所有的列定义之后定义,要显式指定对哪些列建立列级约束,与列定义之间采用英语逗号,隔开

如果是对多列建联合约束,只能使用表级约束语法

1.非空约束(NOT NULL)

 

全文 >>

MySQL学习笔记——基本语法

SQL——结构化查询语言(Structured Query Language)

1. 字符集和大小写

SQL语言不区分大小写,建议关键字用大写,但是字符串常量区分大小写

字符集

1
2
3
4
5
6
7
8
9
character_set_client:服务器将系统变量character_set_client作为客户端发送语句时使用的字符集。
character_set_connection:用于没有字符集介绍器指定的字面量和用于数字到字符串转换的字符集。
character_set_database:默认数据库使用的字符集。每当默认数据库更改时,服务器都会设置此变量。
character_set_filesystem:文件系统字符集。
character_set_results:用于向客户端返回查询结果的字符集。这包括结果数据(如列值)、结果元数据(如列名)和错误消息。
character_set_server:服务器的默认字符集。如果你设置了这个变量,你还应该设置collation_server来指定字符集的排序规则。
character_set_system:服务器用于存储标识符的字符集。
character_sets_dir:安装字符集的目录。

MySQL5.7的默认字符集character和排序字符集collation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
mysql> show variables like '%character%';
+--------------------------+--------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /opt/rh/rh-mysql57/root/usr/share/rh-mysql57-mysql/charsets/ |
+--------------------------+--------------------------------------------------------------+
8 rows in set (0.00 sec)

mysql> show variables like '%collation%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database | latin1_swedish_ci |
| collation_server | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)

MySQL8.0的默认字符集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
mysql> show variables like '%character%';
+--------------------------+--------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | utf8mb4 |
| character_set_system | utf8mb3 |
| character_sets_dir | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+
8 rows in set (0.00 sec)

mysql> show variables like '%collation%';
+-------------------------------+--------------------+
| Variable_name | Value |
+-------------------------------+--------------------+
| collation_connection | latin1_swedish_ci |
| collation_database | utf8mb4_0900_ai_ci |
| collation_server | utf8mb4_0900_ai_ci |
| default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci |
+-------------------------------+--------------------+
4 rows in set (0.00 sec)

查看mysql table字段的字符集

MySQL5.7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql> create table user
(
id bigint unsigned auto_increment comment '主键' primary key,
username varchar(128) not null comment '用户名',
email varchar(128) not null comment '邮箱'
)
comment '用户表' charset=utf8mb4;

mysql> SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'default' and TABLE_NAME = 'user';
+-------------+--------------------+--------------------+
| COLUMN_NAME | CHARACTER_SET_NAME | COLLATION_NAME |
+-------------+--------------------+--------------------+
| id | NULL | NULL |
| username | utf8mb4 | utf8mb4_general_ci |
| email | utf8mb4 | utf8mb4_general_ci |
+-------------+--------------------+--------------------+
3 rows in set (0.00 sec)

或者

全文 >>

使用confluent schema registry将protobuf schema转换成avro schema

confleunt提供了一些方法,可以将protobuf schema转换成avro schema,用于支持将kafka protobuf序列化的message落盘成avro格式的文件

1.引入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<repositories>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
<repository>
<id>confluent</id>
<url>https://packages.confluent.io/maven/</url>
</repository>
</repositories>

<dependencies>
<!--pb-->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.21.7</version>
</dependency>
<!--confluent-->
<dependency>
<groupId>io.confluent</groupId>
<artifactId>kafka-schema-registry</artifactId>
<version>7.1.1</version>
</dependency>
<dependency>
<groupId>io.confluent</groupId>
<artifactId>kafka-protobuf-provider</artifactId>
<version>7.1.1</version>
</dependency>
<dependency>
<groupId>io.confluent</groupId>
<artifactId>kafka-connect-avro-data</artifactId>
<version>7.1.1</version>
</dependency>
<dependency>
<groupId>io.confluent</groupId>
<artifactId>kafka-connect-protobuf-converter</artifactId>
<version>7.1.1</version>
</dependency>
<dependency>
<groupId>io.confluent</groupId>
<artifactId>kafka-connect-avro-data</artifactId>
<version>7.1.1</version>
</dependency>
<!--kafka-->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>connect-api</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>

2.定义protobuf schema

定义一个protobuf schema

1
2
3
4
5
6
7
8
9
10
11
12
syntax = "proto3";
package com.acme;

message MyRecord {
string f1 = 1;
OtherRecord f2 = 2;
}

message OtherRecord {
int32 other_id = 1;
}

编译java代码

1
2
protoc -I=./ --java_out=./src/main/java ./src/main/proto/other.proto

得到schema的java代码

3.将protobuf schema转换成avro schema

confluent schema registry在处理处理protobuf,avro,json格式的数据的时候,会统一先将其转换成connect schema格式的数据,然后再将其写成parquet,avro等具体的文件格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import com.acme.Other;
import io.confluent.connect.avro.AvroData;
import io.confluent.connect.avro.AvroDataConfig;
import io.confluent.connect.protobuf.ProtobufData;
import io.confluent.kafka.schemaregistry.protobuf.ProtobufSchema;
import io.confluent.kafka.schemaregistry.protobuf.ProtobufSchemaUtils;
import org.apache.kafka.connect.data.SchemaAndValue;

public class ProtobufToAvro {

public static void main(String[] args) {
// 初始化protobuf定义的类
Other.MyRecord obj = Other.MyRecord.newBuilder().build();
// 获取pb schema
ProtobufSchema pbSchema = ProtobufSchemaUtils.getSchema(obj);
ProtobufData protobufData = new ProtobufData();
// SchemaAndValue result = protobufData.toConnectData(pbSchema, obj);
// System.out.println(result);

AvroDataConfig avroDataConfig = new AvroDataConfig.Builder()
.with(AvroDataConfig.SCHEMAS_CACHE_SIZE_CONFIG, 1)
.with(AvroDataConfig.CONNECT_META_DATA_CONFIG, false)
.with(AvroDataConfig.ENHANCED_AVRO_SCHEMA_SUPPORT_CONFIG, true)
.build();
AvroData avroData = new AvroData(avroDataConfig);
// 先将protobuf schema转换成connect schema,然后再转换成avro schema
org.apache.avro.Schema avroSchema = avroData.fromConnectSchema(protobufData.toConnectSchema(pbSchema));
System.out.println(avroSchema);
}

}

全文 >>

Hive学习笔记——安装hive客户端

hive client安装文档

1
2
https://cwiki.apache.org/confluence/display/Hive/GettingStarted

hive 配置官方文档

1
2
https://cwiki.apache.org/confluence/display/hive/configuration+properties

hive 配置中文文档

1
2
https://www.docs4dev.com/docs/zh/apache-hive/3.1.1/reference/Configuration_Properties.html

avro学习笔记——实现序列化和反序列化

1.使用java语言来实现avro序列化和反序列化#

使用DatumWriter和DatumReader对avro进行序列化和反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public static <T> byte[] binarySerializable(T t) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
BinaryEncoder binaryEncoder = EncoderFactory.get().binaryEncoder(out, null);
DatumWriter<T> writer = new SpecificDatumWriter<T>((Class<T>) t.getClass());
try {
writer.write(t, binaryEncoder);
binaryEncoder.flush();
out.flush();
} catch (IOException e) {
LOGGER.error("binary serializable error");
e.printStackTrace();
}
LOGGER.debug("ByteArrayOutputStream = {}", new String(out.toByteArray()));
return out.toByteArray();
}


public static <T> T binaryDeserialize(byte[] bytes, Schema schema) {
try {
BinaryDecoder binaryDecoder = DecoderFactory.get().binaryDecoder(bytes, null);
DatumReader<T> datumReader = new SpecificDatumReader<T>(schema);
T read = datumReader.read(null, binaryDecoder);
return read;
} catch (IOException e) {
LOGGER.error("binary deserialize error");
e.printStackTrace();
}
return null;
}

使用Twitter 的 Bijection 类库来实现avro对象的序列化和反序列化

参考:Kafka 中使用 Avro 序列化框架(二):使用 Twitter 的 Bijection 类库实现 avro 的序列化与反序列化

 

2.使用python语言来实现avro序列化和反序列化#

 

3.使用go语言来实现avro序列化和反序列化#

 

 

SpringMVC学习笔记——ServletConfig和ServletContext

1.只有在第一次请求服务器产生实例的时候才会调用init()方法,有一种办法能在服务器一启动的时候就加载init()方法。

即服务器启动即加载Servlet,且按数字大小顺序实例化Servlet。

方法:

  创建一个TestObject.java

  在web.xml中的1,数字小的Servlet将先启动。

  再创建一个TestObject2.java,然后在web.xml中写2

  

    1>在Servlet的配置文件中,可以使用一个或多个标签为servlet配置一些初始化参数。(配置在某个servlet标签或者整个web-app下)

        2>当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,

      并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

 

全文 >>