单个模块获取信息
以cpu为例来聊聊不同的获取方法和获取的数据类型
首先展示一下成果,这里使用的还是老师的方法,利用cat /proc/cpuinfo
提取信息。
scott@scott-virtual-machine:/home$ python3 cpu_con.py
{'cpu_count': 2, 'cpu_physical_count': 0, 'cpu_model': ' Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz'}
在之前的dmidecode
的几种用法里,我也发现了dmidecode模块可以获取linux的cpuinfo信息。
如果用-t
获取的是所有相关cpu的信息,而用-s
的方法,据说可以获取一种cpu信息。尝试了一下有点绝望。-s processor-frequency
一次性跳出来大概八十多条一模一样的信息,大概这个processor真的代表的不是cpu的意思,但是八十条信息的内容的确是cpu频率。这就很尴尬了,再联想到老师最开始用的那个-t 1
后缀,在下觉得事情一定不是这么简单,肯定还有我不知道的特别dmidecode技巧!
果然,简单地搜索dmidecode常用,就能获得以下信息:
对于大部分普通服务器用户来说,我们选择VPS、服务器产品的时候比较关心的是产品的费用、服务器的速度以及稳定性,更有就是服务商家的服务(尤其不能跑路)。随着我们使用服务器时间的推移,以及会看到各个不同的商家产品的时候,就会需要有所对比,严谨的用户会更为的关注产品的硬件配置信息。
以下就是7条常用的dmidecode命令:
# 主板
dmidecode -t 2
# 内存
dmidecode -t 16
# 查看当前内存数和插槽数
dmidecode|grep -P -A5 "Memory Device" |grep Size
# 查看内存条数
dmidecode -t 17
# **查看CPU信息**
dmidecode -t 4
# **查看服务器硬盘信息**
cat /proc/scsi/scsi
# **dmidecode查看内存速率**
dmidecode|grep -A16 "Memory Device"|grep 'Speed'
详解:http://www.linuxidc.com/Linux/2015-12/126814.htm
输了上面的命令,发现。。。。并没有什么卵用。。还是跳一大堆爆炸多的信息
但是分析了需求之后,我发现只要摘取其中的一条即可获得我们需要的全部信息
Handle 0x0083, DMI type 4, 42 bytes
Processor Information
Socket Designation: CPU #127
Type: Central Processor
Family: Unknown
Manufacturer: GenuineIntel
ID: E9 06 00 00 FF FB AB 1F
Version: Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz #看到了吗朋友
Voltage: 3.3 V
External Clock: Unknown
Max Speed: 30000 MHz
Current Speed: 2500 MHz
Status: Populated, Disabled By BIOS
Upgrade: ZIF Socket
L1 Cache Handle: 0x0113
L2 Cache Handle: 0x0193
L3 Cache Handle: Not Provided
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Core Count: 2 # 看到了吗朋友,CPU数量
Core Enabled: 2
Characteristics:
64-bit capable
Multi-Core
Execute Protection
本来想来一个“看到了吗”三连的,但是那个物理核心数好像没找到。。。大概是在core-count和core-enable中有一个是代表物理核心数的。总之在linux上道行尚浅,就先不在这里上耽误太多时间了(坑,待填)
作为参考,再上一段shell,也是用dmidecode采集的信息,但是他就已经在命令上精简筛选过了一些字段,让信息更加清晰
#!/bin/bash
echo "IP:"
ifconfig |grep "inet addr"|grep -v 127.0.0.1|awk '{print $2}'|awk -F ':' '{print $2}'
echo "Product Name:"
dmidecode |grep Name
echo "CPU Info:"
dmidecode |grep -i cpu|grep -i version|awk -F ':' '{print $2}'
echo "Disk Info:"
parted -l|grep 'Disk /dev/sd'|awk -F ',' '{print " ",$1}'
echo "Network Info:"
lspci |grep Ethernet
echo "Memory Info:"
dmidecode|grep -A5 "Memory Device"|grep Size|grep -v No
echo "Memory number:"`dmidecode|grep -A5 "Memory Device"|grep Size|grep -v No|wc -l`
为什么这么想要使用这个dmidecode模块?
因为觉得如果所有的信息获取能够通过相同的模块进行获取,那么返回过来的output格式肯定相近,都可以通过一个预设的response字典去用key匹配获取对应的值,从而降低代码重复率。
加密发送部分
重要模块:crypto
但事实上……它叫cryptodome
这个是个大坑啊,一开始老师的确跟我们介绍的是crypto,并且经过一段时间的准备,老师在他的代码上使用的也的确是真正的crypto。
但是我查了一下资料,这个模块其实在很早的时候已经停止更新维护,所以现在在网上能下载到的,大部分都是python2.7时代的crypto编译版本,如果是python3.x版本的,就更加是编译后的版本。
但是由于本人和同桌等一干热血少年是追逐时代潮流的时尚boy,用的是python3.6版本……
缘,妙不可言……这个这么多大佬都推荐使用的加密模块真的就不再更新,只能通过前人代代相传的包来进行安装了吗?
这个模块只是被整合为cryptodome
。两个包结构一样,作用相同,内部的东西我就不去深究了。但是在调用的时候又出现了一些关于大小写的小插曲。总之直接公布正确答案就可以了:
cryptodome模块的安装和导入
-
安装:
pip3 install cryptodome
pip3 install cryptodomex
-
导入:
from Cryptodome.Cipher AES
这里我们使用的是AES认证方式,其他的以此类推
加密解密代码
为了测试方便,我把加密解密写在一个类里面,因为考虑到中控机采集方式中,接收数据和采集数据均需要进行加密解密。
# 测试pycryptodome的使用
from Cryptodome.Cipher import AES
from binascii import b2a_hex,a2b_hex
class MyCrypto():
def __init__(self,key):
self.key_len=len(key)
# if not self.key_len==16 and not self.key_len==24 and not self.key_len==32:
# raise Exception('lenth of key must be 16/24/32 !!!') self.key=key
self.mode=AES.MODE_CBC
def en_this(self,text):
"""
被加密的铭文长度必须是key长度的整数倍,如果不够,就用 进行填充转换成16进制的字符串。
不用空格是为了避免不可见的ascii在显示的时候表示不清晰
:param text: :return:
"""
text=bytearray(text,encoding='utf-8')
# 将需要传送的字符串变为可以操作的字节类型bytearray
cryptor=AES.new(self.key,self.mode,self.key)
# 生成一个AES加密对象,这个传参中传入两个self.key,第一个是必须要传的,第二个在源码里看来应该不是必须的
# count=len(text)
# add=self.key_len-(count%self.key_len) # text=text+(' '*add)
v1 = len(text)
v2 = v1 % 16
if v2 == 0:
v3 = 16
else:
v3 = 16 - v2
for i in range(v3):
text.append(v3)
text=text.decode('utf-8')
text=text.encode('utf-8')
# 将“可以操作的字节类型bytearray”转换成不可操作的字节类型“bytes”
self.ciphertext=cryptor.encrypt(text)
return self.ciphertext
def de_this(self,text):
cryptor = AES.new(self.key,self.mode,self.key)
"""
解密时去掉最后n位数字n
:param text: :return:
"""
result=cryptor.decrypt(text)
data = result[0:-result[-1]]
print(result[-1])
print(data)
return str(data,encoding='utf-8')
if __name__=="__main__":
key=b'fshlgihsesliengl'
mc=MyCrypto(key)
e=mc.en_this('沙河屎王,顺沙路屎上漂,帅到爆炸')
d=mc.de_this(e)
print(e,'
',d)
这里还有一点坑就是,这个转换“可变的bytesarry类型和不可变的bytes类型”。老师提供了以下方法:
b''.join()
经过测试并没有用。
小小的对这个模块的总结
在这个项目其实有两个地方用到了加密,一个是在这里对数据进行加密(POST发送方式加密),后面在sever端其实对GET方式请求也有加密。这两种加密有不少可以借鉴的想法。这里就不多夸了,免得大郎太得意。
对client端的总结
理清client端的思路之后,可以发现client端的分工很明确,唯一还有点遗憾的就是不能写出基础信息的通用模块。这里面还是有很多信息可以去挖掘学习的,除了linux方面的之外,python的加密,Django request.post方法也还不是很了解。这些点都留在项目标记的地方,以后时间充裕了再回来继续补充。