非常简单的sqlite入门教程

简单的sqlite入门教程

安装

进入sqlite的官网:https://www.sqlite.org/index.html
点击download:
sqlite下载
在这里插入图片描述
下载后解压。

注:如果想要在任意文件目录都可以使用sqlite,请把解压的文件夹加入到环境变量path中。

使用

解压后在解压文件夹下打开cmd(或者打开cmd切换到解压文件夹),输入命令:

1
sqlite3 students.db

表示使用sqlite3.exe来连接一个叫students的databse(db)。

然后输入:

1
2
3
4
5
create table class1 (
ID int primary key not null,
name text not null,
score int not null
);

这个过程发生了什么?

你在刚才打开的数据库中创建了一张表,表的名字是class1,定义表中的每一行的数据(即每一个学生的信息)分别为:ID、name、score。

其中ID的类型是int,而name的类型为text,socre的类型为int。后面的not null 表示不允许他们的值为空。而ID后面有个primary key,表示数据在存储时默认会以ID从小到大的顺序进行存储。

现在你可以输入

1
.tables

来查看你刚刚建立的那张表,输入后你会看到你刚刚创建的这张表的名字。

接下来我们尝试把这三个学生的数据录入存到表中:
姓名:张三 序号:1 分数:50
姓名:李四 序号:2 分数:80
姓名:王五 序号:3 分数:100

输入这个指令:

1
insert into class1 (ID, name, score) values(1, '张三', 50);

这行指令的意思是,把ID=1,name=’张三’,score=50的信息,插入到了class1这个表中。

按下回车键,张三的信息就会被录入到数据库中了。如何查看此时的数据库中的数据呢?

你只需要:

1
select * from class1;

这行指令可以查看整个class1表的所有数据。

类似的,你不妨试一试把李四和王五的数据也录入到数据库。

我们知道了”select * from class1;”可以查看整个数据库的所有数据,那么如何只查看李四一人的数据呢?
你需要:

1
select * from class1 where name='王五';

这时候你就可以从class1中取出name=’王五’的人的数据了。
那么前面这个星号*是什么意思呢?
他表示取出王五的所有数据(也就是ID、姓名、分数)。

如果我只需要取出王五的分数,不需要其他数据,那么我可以:

1
select score from class1 where name='王五';

如果我要取出王五的ID和分数,那么我可以:

1
select ID,score from class1 where name='王五';

如果我要从class1这个表中删除王五的数据,那么我可以:

1
delete from class1 where name='王五'

其实SQL语句的形式很接近自然语言,所以我们很容易看懂每句话的意思。至此,你已经学会了基本的创建、增删、查询的操作。

进一步学习可以参考:https://www.runoob.com/sqlite/sqlite-tutorial.html

本文地址: https://www.chimaoshu.top/非常简单的sqlite入门教程/

DS栈—波兰式,逆波兰式

DS栈—波兰式,逆波兰式

某校数据结构课一道OJ题

题目描述

表达式有三种表示方法,分别为:

前缀表示(波兰式):运算符+操作数1+操作数2

中缀表示:操作数1+运算符+操作数2

后缀表示(逆波兰式):操作数1+操作数2+运算符

例如:a +b * (c -d ) - e/f

波兰式:-+a*b-cd/ef (运算符在操作数的前面,用递归计算波兰式)

中缀式:a+b*c-d-e/f

逆波兰式:abcd-*+ef/ (运算符在操作数的后面,用栈计算逆波兰式)

​ 中缀表示就是原表达式去掉扣号。

根据表达式求波兰式、逆波兰式都是教材第三章表达式求值的思想。

​ 求波兰式,需要操作数栈(注意不是计算结果入栈,有计算式入栈),运算符栈。区别在于从后往前扫描表达式,‘(’ 换成’)’,’(‘换成‘)’。栈顶运算符优先级>新读入运算符优先级出栈,表3.1中的相同运算符优先级>(从左往右计算)改为<,例如栈顶为‘+‘,新读入的为‘+’,则栈顶优先级<新读入的优先级。

求逆波兰式,只需要运算符栈。操作数直接输出,操作符按表3.1优先级顺序出栈,输出。

​ 输入表达式,求其波兰式和逆波兰式。

输入

测试次数

每组测试数据一行,一个合法表达式

输出

对每组测试数据,输出两行

第一行,表达式的波兰表示

第二行,表达式的逆波兰表示

不同组测试数据间以空行分隔。

样例输入

1
2
3
2
4+2*3-10/5
12+3*5+(2+10)*5

样例输出

1
2
3
4
5
\- + 4 * 2 3 / 10 5
4 2 3 * + 10 5 / -

+ + 12 * 3 5 * + 2 10 5
12 3 5 * + 2 10 + 5 * +

代码

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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#include <iostream>
#include <string>
#include <stack>
using namespace std;

#define space ' '

int getPriority(char a)
{
switch (a)
{
case '*':
case '/':
return 2;
case '+':
case '-':
return 1;
case '(':
case ')':
return 0;
default:
return 0;
}
}

bool isNumber(char temp)
{
return (temp != '+' && temp != '-' && temp != '*' && temp != '/' && temp != '(' && temp != ')');
}

// 逆波兰式只要一个运算符栈就可以,数字直接输出
void reservePolish(string expression)
{
stack<char> operatorStack; // 运算符栈
char ch;

bool theLastCharactorIsNumber = false;
bool theFirst = true;
for (int i = 0; i < expression.size(); i++)
{
char ch = expression[i];

if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
if (operatorStack.empty() || operatorStack.top() == '(')
operatorStack.push(ch);
else
{
// 逆波兰式这里有=,而波兰式没有=
while (getPriority(operatorStack.top()) >= getPriority(ch))
{
if (!theFirst)
cout << space;

cout << operatorStack.top();
operatorStack.pop();

if (operatorStack.empty())
break;
}
operatorStack.push(ch);
}
theLastCharactorIsNumber = false;
theFirst = false;
}
else if (ch == '(') // 这个不能做first
{
operatorStack.push(ch);
theLastCharactorIsNumber = false;
}
else if (ch == ')')
{
while (!operatorStack.empty())
{
if (operatorStack.top() == '(')
{
operatorStack.pop();
break;
}
else
{
if (!theFirst)
cout << space;

cout << operatorStack.top();
operatorStack.pop();
}
}
theLastCharactorIsNumber = false;
theFirst = false;
}
// 数
else
{
if (theLastCharactorIsNumber || theFirst)
cout << ch << flush;
else
cout << space << ch << flush;

theLastCharactorIsNumber = true;
theFirst = false;
}
}
while (!operatorStack.empty())
{
if (!theFirst)
cout << space;

cout << operatorStack.top();
operatorStack.pop();
}
cout << endl;
}

// 波兰式:把)和(倒换,然后从后往前读,>=变成>,最后逆序输出
void polish(string expression)
{
stack<char> operatorStack; // 运算符栈
stack<char> output;
char ch;

bool theLastCharactorIsNumber = false;

// 从后往前
for (int i = expression.size() - 1; i >= 0; i--)
{
char ch = expression[i];

if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
if (operatorStack.empty() || operatorStack.top() == ')')
operatorStack.push(ch);
else
{
// 逆波兰式这里有=,而波兰式没有=
while (getPriority(operatorStack.top()) > getPriority(ch))
{
// cout << operatorStack.top() << " ";
output.push(space);
output.push(operatorStack.top());
operatorStack.pop();

if (operatorStack.empty())
break;
}
operatorStack.push(ch);
}
}
else if (ch == ')')
{
operatorStack.push(ch);
}
else if (ch == '(')
{
while (!operatorStack.empty())
{
if (operatorStack.top() == ')')
{
operatorStack.pop();
break;
}
else
{
// cout << operatorStack.top() << " ";
output.push(space);
output.push(operatorStack.top());
operatorStack.pop();
}
}
}
// 数
else
{
// 从后往前读,而前一个读取的是数字,所以要
if (!theLastCharactorIsNumber)
{
output.push(space);
}

output.push(ch);
}
theLastCharactorIsNumber = isNumber(ch);
}
while (!operatorStack.empty())
{
// cout << operatorStack.top() << " ";
output.push(space);
output.push(operatorStack.top());
operatorStack.pop();
}

// 倒叙输出
while (!output.empty())
{
char temp = output.top();

// 判断栈是否只剩最后一个空格(不输出最后一个空格)
if (temp == space)
{
output.pop();
if (output.empty())
{
cout << endl;
return;
}
else
{
cout << space << flush;
continue;
}
}
cout << temp << flush;
output.pop();
}
cout << endl;
}

int main()
{
int tryTimes;
cin >> tryTimes;

for (int i = 0; i < tryTimes; i++)
{
string expression;
cin >> expression;

polish(expression);
reservePolish(expression);

if (i != tryTimes - 1)
{
cout << endl;
}
}
return 0;
}

参考资料:

https://blog.csdn.net/linraise/article/details/20459751

https://zhuanlan.zhihu.com/p/141207867

本文地址: https://www.chimaoshu.top/DS栈—波兰式,逆波兰式/

为1M小水管的Minecraft服务器加速的各种尝试

遇到的问题

阿里云的学生机,10块钱一个月的那种,只有1Mbps的带宽。1Mbps是什么概念呢?就是公网下行带宽最大是1×1024÷8 = 128 kb/s,每秒最多128kb的速度,开mc服务器基本顶不住。一个只有三人的私人服务器,差不多两人就能把带宽占满,三人就开始卡,如何解决呢?

首先从Minecraft服务器的设置出发

Minecraft维基百科上关于服务器的设置文件server.properties讲的非常清楚,其中有两处地方可以大大减少服务器的带宽,他们分别是:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

其中network-compression-threshold与数据包的压缩有关,他的本质就是拿CPU资源去换带宽资源,我的设置是0,即压缩全部数据包。

view-distance是玩家的视野距离,我一直开着1(最低配置),不过玩家几乎是感觉不到它的存在的,可以放心调低。

而第三个是Linux专用的,可以优化数据包的收发。

通过这两个配置,我的Minecraft服务器已经基本够3人玩了,但是3人的时候还是会轮流变卡,一看阿里云后台的公网出口带宽,都是全满的。还是需要解决问题!

在本机运行Minecraft服务器,使用阿里云的服务器做中转?

用frp进行端口映射,把本地的25565端口映射到云端上,这样用本机的CPU就会好一些,并且frp可以做压缩。

最终效果:比直接开在云端还慢,因为公网下行数据实际上更多了,阿里云需要在我的电脑和朋友的电脑之间做数据中转。效果很差,放弃了,强烈不推荐。

P2P的Minecraft服务器?

既然做中转会受到阿里云的带宽限制,那如果我们使用P2P呢?直接在两台电脑直接建立对等连接,而云服务器只在一开始负责帮两台电脑建立连接,等到连接建立后,数据是不经过阿里云做中转的,直接在我的朋友的电脑直接流通。

于是我开始着手寻找能够进行P2P打洞的软件,刚开始用了frp的一个P2P打洞功能,叫做XTCP,服务端配置是这样的:

1
2
3
[common]
bind_port = 7000
bind_udp_port = 7001

我的电脑客户端配置是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# frpc.ini
[common]
# 你的frp服务器的公网ip
server_addr = xx.xx.xx.xxx
# 你的frp服务器的默认端口
server_port = 7000

[mc]
type = xtcp
# 只有 sk 一致的用户才能访问到此服务
sk = oc7D!PgY&guFBPwoEfKq
local_ip = 127.0.0.1
# 远程桌面的本地端口号
local_port = 25565

朋友的电脑客户端的配置是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# frpc.ini
[common]
# 你的frp服务器的公网ip
server_addr = xx.xx.xx.xx
# 你的frp服务器的默认端口
server_port = 7000

[mc_visitor]
type = xtcp
# stcp 的访问者
role = visitor
# 要访问的 stcp 代理的名字
server_name = mc
# 只有 sk 一致的用户才能访问到此服务
sk = oc7D!PgY&guFBPwoEfKq
# 绑定本地端口用于访问 远程桌面 服务
bind_addr = 127.0.0.1
bind_port = 6000

这样,(理论上)只要朋友访问127.0.0.1:6000就能访问到我的电脑上的Minecraft服务器了。然而最终失败了,连接不能顺利地建立。本来frp的打洞功能也非常不成熟,受到NAT类型的影响。

然后我又开始寻找其他的P2P解决方案,最终找到了NPS

和frp一样,也是Github上开源的项目,也都是用Go语言写的。

https://github.com/ehang-io/nps

于是开始了我的部署之路,安装过程只要照着(官方教程)[https://ehang-io.github.io/nps/#/install]来就行了。最终登陆管理面板是这样的:

管理面板

然后照着官方教程,创建一个客户端:

新建客户端

参数可以随便填,然后复制最下面红色的那行命令:

复制

然后下载nps的客户端到我运行Minecraft服务器的本机电脑,打开cmd切换到客户端exe所在的目录下,把命令复制进去运行。注意这里不能使用PowerShell,否则会连接不上。如果cmd显示无法运行,就把那行命令前面的./去掉。

之后去创建一个P2P连接,客户端ID要和上面我们创建的客户端的ID一致。

P2P连接

然后像前面一样,复制最下面的命令:

复制命令

其中那个“唯一表示密钥”是自动生成的。然后同理让朋友在他自己电脑上下载nps的客户端并cmd运行命令。之后朋友只要在mc服务器的地址填上”127.0.0.1:2000”(默认端口是2000,可以自己换),就能访问到我本机开在127.0.0.1:25565的Minecraft服务器了。

现在带宽已经没问题了,但是朋友还是反馈很卡,也找不出原因,所以就暂时放弃了这个方案。

阿里云不同实例内网互联+另一台服务器流量转发?

因为阿里云所谓的1Mbps的带宽限制,只是公网下行带宽的限制,对其他带宽(比如上行带宽、或者内网带宽)是没有限制的。我和同学在不同的阿里云账号下各拥有一台阿里云服务器,并且在同地域(这意味着内网互联是免费的)。于是我就有了另一个思路,依然把Minecraft服务器开在一台云服务器上,但是一部分玩家的流量直连云服务器,另一部分玩家通过连接另一台闲置的云服务器,然后由闲置的云服务器把流量转发到Minecraft服务器。这样带宽就变成两台服务器加起来2Mbps了。

首先是探索了半天阿里云的内网互联,由于阿里云的业务一直变化,所以网上找到的教程全都过期了,只好去看阿里云官方的文档。

首先你要在专有网络–快速链接–高速通道,找到云企业网,然后创建云企业网实例。

云企业网

先把你自己账号下的实例绑定进去,之后照着阿里云文档操作。

阿里云帮助文档

然后登陆同学的账号,进行企业网授权,详情查看搜索阿里云文档关于授权部分内容。之后再登陆你的账户把同学的实例加入企业网,这样两个实例就可以通网了。

之后,使用frp,把Minecraft服务器的25565端口映射到另一台服务器上(记得ip不要填公网ip,要填内网ip,这样才不会占用公网下行带宽),就可以了,具体不再赘述。你也可以配置服务器的防火墙规则或者使用Nginx做端口转发,也是可以的。

用frp的优点是他可以进行数据压缩,进一步减少了带宽。

总的来说,这个方案的效果还不错。

本文地址: https://www.chimaoshu.top/为1M小水管的Minecraft服务器加速/

在win10自用机上使用Nginx+Docker部署bitwarden_rs

最初的想法

从很久之前就一直想要找到1Password的替代品,当时自己用AES256 + RSA2048的加密方式,写一个服务端和客户端,只能在终端黑窗口里面运行,总归没有这些成熟的产品用得爽。后来了解到了Bitwarden,想部署到服务器上,想了想不如部署到本机上吧,不然服务器一到期就一直得续费。原版的Bitwarden服务端的服务对象是比较广的,资源消耗也比较大,总归不是办法。后来了解到Bitwarden_rs,是大佬用Rust重新写的一个不那么耗费资源的版本,就决定是它了。

部署过程

首先是Bitwarden的部署

首先需要在win10上安装Docker,不再赘述。
然后根据 Github上官方给出的说明 ,只要打开命令行,输入下面命令就可以安装完成并部署到localhost中。

首先拉取镜像:

1
docker pull bitwardenrs/server:latest

然后是运行

1
docker run -d --name bitwarden -v /把这个路径换成你本机要存储的数据的绝对路径/:/data/ -p 80:127.0.0.1:80 bitwardenrs/server:latest

如果要开启管理面板就加个参数,把上面命令换成这个:

1
docker run -d --name bitwarden -e ADMIN_TOKEN=换成你的管理面板登陆密码 -v /把这个路径换成你本机要存储的数据的绝对路径/:/data/ -p 127.0.0.1:80:80  bitwardenrs/server:latest

记得把路径换成你本机要存储这些密码数据的路径,如果不设置的话,你电脑一关机,数据就都没了。

当然你也可以把127.0.0.1:80:80中的”127.0.0.1:80”换成你要部署的本机ip的端口,如果想要部署在0.0.0.0(所有指向本机的ip)就直接输入80:80就好了。由于后面我要用Nginx进行反向代理,所以我是部署在了127.0.0.1。

只要你的Docker是正常的(包括网络连接正常),那么运行这两行命令之后,在浏览器访问http://localhost就可以正常访问到了。

bitwarden

现在你已经可以在本机使用Bitwarden的服务了,如果想让自己的手机或其他设备也安全地用上,请继续往下看。

接下来是Nginx进行反向代理

先到Nginx官网http://nginx.org/上下载最新的适用于Windows的Nginx
Nginx官网
Nginx下载
下载Nginx压缩包之后找一个文件夹解压,我解压到了/bitwarden文件夹下。

然后再bitwarden/conf/目录下创建一个文件夹,命名为cert。

然后去给你的域名申请一个HTTPS证书,我是用了阿里云免费的证书,下载Nginx版本的证书(包含xxx.key和xxx.pem两个文件),然后把这两个文件放到cert下面。

然后编辑bitwarden/conf/nginx.conf 的配置,如下:

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
worker_processes 1;

events {
worker_connections 1024;
}


http {
# HTTPS server
server {

listen 443 ssl; #SSL协议访问端口号为443。此处如未添加ssl,可能会造成Nginx无法启动。
server_name localhost; #将localhost修改为您证书绑定的域名,例如:www.example.com。
ssl_certificate cert/domain name.pem; #将domain name.pem替换成您证书的文件名。
ssl_certificate_key cert/domain name.key; #将domain name.key替换成您证书的密钥文件名。
ssl_session_timeout 10s;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #使用此加密套件。
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #使用该协议进行配置。
ssl_prefer_server_ciphers on;

location / {
proxy_pass http://localhost;
}
}
}

最后记得设置域名的解析记录,把你要的域名解析到你电脑的IP地址,之后就能通过域名进行https访问了。

我是解析到了我的内网IP地址,所以说我的手机需要和电脑连接同一个wifi才能访问到电脑的服务器。如果你想要让所有设备都能访问,那么可以用frp把你的电脑的443端口映射到云服务器上,同时把域名解析的ip设置你的云服务器的ip。(或者直接把bitwarden部署到你的云服务器上)

至此,已经可以使用https的方式,访问服务器了,部署已经完成。

客户端

Bitwarden提供了多种客户端,有安卓、IOS的APP端、浏览器web端、浏览器插件、win、linux、macOS的桌面端、甚至还有好几个命令行的版本,全部可以从官网下载。https://bitwarden.com/#download

启动脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ProcessName = "docker desktop"
if((get-process $ProcessName -ErrorAction SilentlyContinue) -eq $Null)
{
echo "Docker is not running,strating...."
start "Docker Desktop"
sleep 20
}
else
{
echo "Process is running."
}

docker start bitwarden
.\nginx

将脚本保存为xxx..ps1,然后把这个脚本放到与Nginx.exe同目录下,把docker.exe的快捷方式也放到这个目录下(或者设置docker为开机启动)。

你可以把这个脚本设置为开机启动,你可以另外写一个run.bat

1
2
@echo off
powershell .\run.ps1

然后win+r,输入shell:startup后回车,打开控制开机自启动的文件目录,然后把这个bat的快捷方式放进去文件夹,之后开机就会自启动了。

结束脚本

1
2
3
.\nginx -s stop
docker stop 822faa38fd55
choice /t 2 /d y /n >nul

其中822faa38fd55指的是容器的ID(可以通过docker ps -a来查看容器的ID)
将脚本保存为xxx.bat

本文地址: https://www.chimaoshu.top/在win10自用机上使用Nginx-Docker部署bitwarden-rs/

关于win10下深信服sslvpn的客户端流量分流/不同网卡流量分流

​ 如果你的单位或学校使用了深信服的sslvpn,有时候会有需要流量分流的场景,比如访问internet不直连而是走了sslvpn,比如sslvpn设定的路由策略与其他连接冲突导致无法上公网之类的问题。

踩了一下午坑,终于解决了问题。

​ 解决的方法是修改路由表。通过修改路由表可以实现对不同的ip段走不同的连接模式。

​ 如果你够细心的话,会发现用了深信服的vpn电脑会多了一个网络适配器
适配器

理论上这个方法不止可以用于深信服的vpn,只要是多个网卡/网络适配器的分流都适用。

打开cmd,输入 ipconfig/all 查看你要分流的两个网卡/网络适配器的网关ip

这个2开头的ip地址是虚拟的ip地址

然后输入 route print -4 显示ipv4的路由规则

路由表
可以看到路由表规定了不同的目标ip(包括目标的子网掩码)会走不同的网关,所以我们可以用
route add 和 route delete 命令对路由表进行删改,至于具体命令用法,百度一大堆,不再赘述,而且我也忘了。

本文地址: https://www.chimaoshu.top/关于深信服sslvpn的客户端流量分流/

filezilla配置ssl证书过程中出现'Failed to load SSL Libraries'、'Cannot create certificate.Failed to initialize SSL library'、'Could not load certificate file: error:02001003:system library:fopen:No such process (0)'

‘Failed to load SSL Libraries’
‘Cannot create certificate.Failed to initialize SSL library’
以上两个问题的解决方法:
1.系统更新
2.卸载干净,然后从官网下载安装最新的版本
3.不要用中文版的filezilla server

‘Could not load certificate file: error:02001003:system library:fopen:No such process (0)’
解决方法:
1.检查证书所在文件夹是否有赋予足够的用户权限
2.以管理员身份运行filezilla server
3.证书的存放路径不要有中文

本文地址: https://www.chimaoshu.top/filezilla配置ssl证书过程中出现-Failed-to-load-SSL-Libraries-、-Cannot-create-certificate-Failed-to-initialize-SSL-library-、-Could-not-load-certificate-file-error-02001003-system-library-fopen-No-such-process-0/

ImportError cannot import name ''DerBitString'' from ''Crypto.Util.asn1''

今天用到 PyCryptodome 模块的时候,当我用到了

1
from Crypto.PublicKey import RSA

的时候,出现了错误:
ImportError : cannot import name ‘’DerBitString’’ from ‘’Crypto.Util.asn1’’。
找到了这篇博客官方文档,都提到了Windows下同时安装PyCryptodome和PyCrypto会出现这个问题。
给出的解决方案是:

1
2
3
pip uninstall crypto
pip uninstall pycryptodome
pip install pycryptodome

但我并没有安装crypto模块也出现了问题,后来发现只要

1
2
pip uninstall pycryptodome
pip install pycryptodome

重新装一下pycryptodome问题就解决了。

本文地址: https://www.chimaoshu.top/ImportError-cannot-import-name-DerBitString-from-Crypto-Util-asn1/

(详细版)基于frp与v2ray的几种校园网内网穿透的方案

非零基础请移步(简略版)基于frp与v2ray的几种校园网内网穿透的方案

设备

方案一:简单的frp socks5/http代理

方案二:用frp映射v2ray的inbound端口+校外设备http/socks5代理

方案三:用frp映射v2ray的inbound端口+校外设备使用v2ray/ssr连接

方案四:用v2ray自带的反向代理功能

方案五:用路由器代替校内主机

阅读更多...

(简略版)基于frp与v2ray的几种校园网内网穿透的方案

如果是零基础,请移步(详细版)基于frp与v2ray的几种校园网内网穿透的方案

方案一:简单的frp socks5/http代理

方案二:用frp映射v2ray的inbound端口+校外设备http/socks5代理

方案三:用frp映射v2ray的inbound端口+校外设备使用v2ray/ssr连接

方案四:用v2ray自带的反向代理功能

方案五:用路由器代替校内主机

阅读更多...
  • © 2020 Jt10n
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信