.json 打印数据不遵循 Python 中的字典顺序
The .json printed data doesn't respect the dictionary order in Python
我正在分析一些实时捕获的数据,以解析一些 TLS Client Hello 信息。
捕获和分析数据后,我使用 python.
中的字典将 output.txt
文件中的信息打印为 .json
格式
我的问题是 关于 output.txt
文件中的 .json
输出。数据未按顺序打印,这意味着它不遵守字典中数据的顺序 (output_dictionary.py
)。
我用于 .json
输出的词典:
output_dictionary.py
HANDSHAKE = {
"Client_Hello" : {
'Length': 'unknown',
'Version': 'unknown',
'Random': 'unknown',
'Session ID': 'unknown',
'Session ID Length': 'unknown',
'Cipher Suites Length': 'unknown',
'Cipher Suites': 'unknown',
'Compression Method': 'unknown'
}
}
填充字典以便将其打印为 .json
并调用 json_read("output.txt")
的函数:
def parse_client_hello(handshake):
if isinstance(handshake.data, dpkt.ssl.TLSClientHello):
client = dpkt.ssl.TLSClientHello(str(handshake.data))
**HANDSHAKE["Client_Hello"]['Length'] = len(client)**
**HANDSHAKE["Client_Hello"]['Version'] = tls_dictionary('tls_version',client.version)**
**HANDSHAKE["Client_Hello"]['Random'] = hexlify(client.random)**
session_id, pointer = parse(client.data, 1)
**HANDSHAKE["Client_Hello"]['Session ID'] = hexlify(session_id)**
**HANDSHAKE["Client_Hello"]['Session ID Length'] = len(session_id)**
ciphersuites, pointer1 = parse(client.data[pointer:], 2)
ciphersuites, pretty_cipher_suites = parse_ciphers_compressions(ciphersuites, 'cipher_suites')
**HANDSHAKE["Client_Hello"]['Cipher Suites Length'] = len(ciphersuites)**
**HANDSHAKE["Client_Hello"]['Cipher Suites'] = pretty_cipher_suites**
pointer += pointer1
compression_methods, pointer1 = parse(client.data[pointer:], 1)
compression_methods, pretty_compressions = parse_ciphers_compressions(compression_methods,
'compression_methods')
**HANDSHAKE["Client_Hello"]['Compression Method'] = pretty_compressions**
json_read("output.txt")
将字典转换为.json
格式的json.read
函数:
def json_read(filename):
with open(filename, "a") as f:
json.dump(HANDSHAKE, f, indent = 4)
数据如何以 .json
格式打印在 ouput.txt
文件中:
{
"Client_Hello": {
"Session ID Length": 32,
"Length": 236,
"Version": "TLS 1.2",
"Handshake Type": "Client Hello : 1",
"Compression Method": [
"null"
],
"Session ID": "3eadfb1c6243f6aa70a880af598d52873e1fe049f15c3a7e2e6f4a3e4b58fc0e",
"Random": "502143b34cab4a59f947a8da76f58e66215bf709e85f71f7cbfa4ead8e99736b",
"Cipher Suites Length": 15,
"Cipher Suites": [
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_RSA_WITH_AES_128_GCM_SHA256",
"TLS_RSA_WITH_AES_256_GCM_SHA384",
"TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_RSA_WITH_AES_256_CBC_SHA",
"TLS_RSA_WITH_3DES_EDE_CBC_SHA"
]
}
}
问题是 .json
打印的数据不遵守字典顺序,这意味着首先它应该打印长度、版本、随机数等。
有办法解决这个问题吗?
基本上你的问题归结为“保持 keys/values 与初始化字典时声明的顺序相同”。为此,您必须使用 OrderedDict。
OrderedDict 维护您的密钥插入的顺序。
对于您的情况,您可以像下面这样初始化 HANDSHAKE 字典:
from collections import OrderedDict
client_hello_params = ['Length', 'Version', 'Random', 'Session ID', 'Session ID Length', 'Cipher Suites Length', 'Cipher Suites', 'Compression Method']
HANDSHAKE = {
"Client_Hello": OrderedDict((param, 'unknown') for param in client_hello_params)
现在您可以通过更改 client_hello_params 列表中的顺序来保留您想要的任何顺序。
打印这将打印您想要的结果,例如。
import json
HANDSHAKE["Client_Hello"]['Length'] = 10
print(json.dumps(HANDSHAKE))
{"Client_Hello": {"Length": 10, "Version": "unknown", "Random": "unknown", "Session ID": "unknown", "Session ID Length": "unknown", "Cipher Suites Length": "unknown", "Cipher Suites": "unknown", "Compression Method": "unknown"}}
我正在分析一些实时捕获的数据,以解析一些 TLS Client Hello 信息。 捕获和分析数据后,我使用 python.
中的字典将output.txt
文件中的信息打印为 .json
格式
我的问题是 关于 output.txt
文件中的 .json
输出。数据未按顺序打印,这意味着它不遵守字典中数据的顺序 (output_dictionary.py
)。
我用于 .json
输出的词典:
output_dictionary.py
HANDSHAKE = {
"Client_Hello" : {
'Length': 'unknown',
'Version': 'unknown',
'Random': 'unknown',
'Session ID': 'unknown',
'Session ID Length': 'unknown',
'Cipher Suites Length': 'unknown',
'Cipher Suites': 'unknown',
'Compression Method': 'unknown'
}
}
填充字典以便将其打印为 .json
并调用 json_read("output.txt")
的函数:
def parse_client_hello(handshake):
if isinstance(handshake.data, dpkt.ssl.TLSClientHello):
client = dpkt.ssl.TLSClientHello(str(handshake.data))
**HANDSHAKE["Client_Hello"]['Length'] = len(client)**
**HANDSHAKE["Client_Hello"]['Version'] = tls_dictionary('tls_version',client.version)**
**HANDSHAKE["Client_Hello"]['Random'] = hexlify(client.random)**
session_id, pointer = parse(client.data, 1)
**HANDSHAKE["Client_Hello"]['Session ID'] = hexlify(session_id)**
**HANDSHAKE["Client_Hello"]['Session ID Length'] = len(session_id)**
ciphersuites, pointer1 = parse(client.data[pointer:], 2)
ciphersuites, pretty_cipher_suites = parse_ciphers_compressions(ciphersuites, 'cipher_suites')
**HANDSHAKE["Client_Hello"]['Cipher Suites Length'] = len(ciphersuites)**
**HANDSHAKE["Client_Hello"]['Cipher Suites'] = pretty_cipher_suites**
pointer += pointer1
compression_methods, pointer1 = parse(client.data[pointer:], 1)
compression_methods, pretty_compressions = parse_ciphers_compressions(compression_methods,
'compression_methods')
**HANDSHAKE["Client_Hello"]['Compression Method'] = pretty_compressions**
json_read("output.txt")
将字典转换为.json
格式的json.read
函数:
def json_read(filename):
with open(filename, "a") as f:
json.dump(HANDSHAKE, f, indent = 4)
数据如何以 .json
格式打印在 ouput.txt
文件中:
{
"Client_Hello": {
"Session ID Length": 32,
"Length": 236,
"Version": "TLS 1.2",
"Handshake Type": "Client Hello : 1",
"Compression Method": [
"null"
],
"Session ID": "3eadfb1c6243f6aa70a880af598d52873e1fe049f15c3a7e2e6f4a3e4b58fc0e",
"Random": "502143b34cab4a59f947a8da76f58e66215bf709e85f71f7cbfa4ead8e99736b",
"Cipher Suites Length": 15,
"Cipher Suites": [
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_RSA_WITH_AES_128_GCM_SHA256",
"TLS_RSA_WITH_AES_256_GCM_SHA384",
"TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_RSA_WITH_AES_256_CBC_SHA",
"TLS_RSA_WITH_3DES_EDE_CBC_SHA"
]
}
}
问题是 .json
打印的数据不遵守字典顺序,这意味着首先它应该打印长度、版本、随机数等。
有办法解决这个问题吗?
基本上你的问题归结为“保持 keys/values 与初始化字典时声明的顺序相同”。为此,您必须使用 OrderedDict。 OrderedDict 维护您的密钥插入的顺序。
对于您的情况,您可以像下面这样初始化 HANDSHAKE 字典:
from collections import OrderedDict
client_hello_params = ['Length', 'Version', 'Random', 'Session ID', 'Session ID Length', 'Cipher Suites Length', 'Cipher Suites', 'Compression Method']
HANDSHAKE = {
"Client_Hello": OrderedDict((param, 'unknown') for param in client_hello_params)
现在您可以通过更改 client_hello_params 列表中的顺序来保留您想要的任何顺序。
打印这将打印您想要的结果,例如。
import json
HANDSHAKE["Client_Hello"]['Length'] = 10
print(json.dumps(HANDSHAKE))
{"Client_Hello": {"Length": 10, "Version": "unknown", "Random": "unknown", "Session ID": "unknown", "Session ID Length": "unknown", "Cipher Suites Length": "unknown", "Cipher Suites": "unknown", "Compression Method": "unknown"}}