Python - 网络传输数据格式【字节流】传输优点及数据格式【字符,字典,字节,二进制,十六进制】的转换

发布时间:2023年12月19日

一. 前言

在网络传输数据时,数据本质上是以二进制形式进行传输的。无论是传输字节还是传输二进制数据,最终都会转化为二进制进行传输。

所以,从传输速度的角度来看,无论是传输字节还是传输二进制数据,实际上是相同的,没有本质区别。传输速度的快慢主要取决于网络连接的带宽、延迟等因素,而不是数据格式的选择。

在一些特定的应用场景下,可能会使用特定的数据格式进行传输。例如,如果传输的是文本信息,可以选择使用字节流传输;如果传输的是图像或音频等二进制数据,可以选择使用二进制流传输。但这些选择更多是基于数据的特点和处理需求,而不是为了提高传输速度。

二. 各个数据大小测试代码

在Python中,可以使用sys.getsizeof()函数来计算一个对象的大小(以字节为单位)。

  • 使用json.dumps()将字典转换为字符串
  • 使用.encode()方法将字符串转换为字节
  • 使用binascii.hexlify()将字节转换为十六进制
  • 使用pickle.dumps()将字典转换为二进制
import json
import pickle
import sys
import binascii

# 示例字典
data = {'name': 'John',
        'age': 30,
        'city': 'New York',
        '角色': '工程师',
        }


def calculate_size(data):
    # 字典转换为字符
    json_str_data = json.dumps(data, ensure_ascii=False)
    json_str_size = sys.getsizeof(json_str_data)

    # 字典转换为字节
    byte_data = json_str_data.encode('utf-8')
    byte_size = sys.getsizeof(byte_data)

    # 字典转换为十六进制
    hex_data = binascii.hexlify(byte_data)
    hex_size = sys.getsizeof(hex_data)

    # 字典转换为二进制
    binary_data = pickle.dumps(data)
    binary_size = sys.getsizeof(binary_data)

    print(f'dict -> str:{json_str_data}')
    print(f'dict -> bytes:{byte_data}')
    print(f'dict -> hex:{hex_data}')
    print(f'dict -> binary:{binary_data}')
    res = {
        'data': {
            'json_str_data': json_str_data,
            'byte_data': byte_data,
            'binary_data': binary_data,
            'hex_data': hex_data,
        },
        'size': {
            'json_str_size': json_str_size,
            'byte_size': byte_size,
            'binary_size': binary_size,
            'hex_size': hex_size,
        },
    }
    return res


def str2dict(str_data):
    # 将JSON字符串转换为字典
    my_dict = json.loads(str_data)
    return my_dict


def hex2dict(hex_data):
    # 将十六进制字符串转换为字节串
    bytes_str = binascii.unhexlify(hex_data)
    # 将字节串转换为JSON字符串
    json_str = bytes_str.decode()
    # 将JSON字符串转换为字典
    my_dict = json.loads(json_str)
    return my_dict


def binary2dict(binary_data):
    # 将二进制数据转换为字典
    my_dict = pickle.loads(binary_data)
    return my_dict


def bytes2dict(bytes_data):
    # 将字节流数据转换为字典
    my_dict = bytes_data.decode('utf-8')
    return my_dict


if __name__ == '__main__':
    # 计算大小
    res = calculate_size(data)
    print("\n====================\n")
    print("字典大小:", sys.getsizeof(data))
    print("字符大小:", res['size'].get('json_str_size'))
    print("字节大小:", res['size'].get('byte_size'))
    print("二进制大小:", res['size'].get('binary_size'))
    print("十六进制大小:", res['size'].get('hex_size'))
    print("\n====================\n")
    print("str to dict:", str2dict(res['data'].get('json_str_data')))
    print("bytes to dict:", bytes2dict(res['data'].get('byte_data')))
    print("hex to dict:", hex2dict(res['data'].get('hex_data')))
    print("binary to dict:", binary2dict(res['data'].get('binary_data')))

运行结果
在这里插入图片描述
从以上运行结果可以看出,使用转换后字节的大小是最小的,因此常用其作为网络数据传输的格式,一般来说,网络传输数据时推荐使用字节进行表示和计算传输速度。这是因为网络传输通常以字节为单位,而且字节更直接地与计算机系统的存储和传输操作相关联。使用字节作为传输单位更加直观和符合实际。

附上其他数据之间转换的方法

import binascii
import struct


def example(express, result=None):
    if result == None:
        result = eval(express)
    print(express, '==>', result)


if __name__ == '__main__':
    print('整数之间的进制转换:')
    print('10进制转16进制', end=':')
    example("hex(16)")
    print("16进制结10进制", end=':')
    example("int('0x10', 16)")
    print("类似的还有octO, bin()")

    print("\n-------------------\n")

    print("字符串转整数:")
    print("10进制字符串", end=": ")
    example("int('10')")
    print("16进制字符串", end=": ")
    example("int('10', 16)")
    print("16进制字符串", end=": ")
    example("int('0x10', 16)")

    print("\n-------------------\n")

    print('字节串转整教:')
    print("转义为short型整数", end=": ")
    example(r"struct.unpack('< hh', bytes(b'\x01\x00\x00\x00'))")
    print("转义为1ong型整教", end=": ")
    example(r"struct.unpack('< L', bytes(b'\x01\x00\x00\x00'))")

    print("\n====================\n")

    print("整数转字节串: ")
    print("转为两个字节", end=": ")
    example("struct.pack('<HH',1,2)")
    print("转为四个字节", end=": ")
    example("struct.pack('<LL',1,2)")

    print("\n-------------------\n")

    print('字符串装字节串:')
    print('字符串编码为字节码', end=": ")
    example(r"'12abc'.encode(' ascii')")
    print('数字或字符数组', end=": ")
    example(r"bytes([1, 2,ord('1'), ord('2')])")
    print('16进制字符串', end=': ')
    example(r"bytes().fromhex('010210')")
    print('16进制字符串', end=': ')
    example(r"bytes(map(ord,'\x01\x02\x31\x32'))")
    print('16进制数组', end=': ')
    example(r'bytes([0x01, 0x02, 0x31, 0x32])')

    print("\n====================\n")

    print("字节串转字符串:")
    print('字节码解码为字符串', end=": ")
    example(r"bytes(b'\x31\x32\x61\x62').decode('ascii')")
    print('字节出传16进制表示,夹带ascii', end=": ")
    example(r"str(bytes(b'lx01\x0212'))[2:-1]")
    print('字节串转16进制表示, 固定两个字符表示', end=": ")
    example(r"str(binascii.b2a_hex(b'\x01\x0212'))[2:-1]")
    print("\n====================\n")

=========================================
运行结果

整数之间的进制转换:
10进制转16进制:hex(16) ==> 0x10
16进制结10进制:int('0x10', 16) ==> 16
类似的还有octO, bin()

-------------------

字符串转整数:
10进制字符串: int('10') ==> 10
16进制字符串: int('10', 16) ==> 16
16进制字符串: int('0x10', 16) ==> 16

-------------------

字节串转整教:
转义为short型整数: struct.unpack('< hh', bytes(b'\x01\x00\x00\x00')) ==> (1, 0)
转义为1ong型整教: struct.unpack('< L', bytes(b'\x01\x00\x00\x00')) ==> (1,)

====================

整数转字节串: 
转为两个字节: struct.pack('<HH',1,2) ==> b'\x01\x00\x02\x00'
转为四个字节: struct.pack('<LL',1,2) ==> b'\x01\x00\x00\x00\x02\x00\x00\x00'

-------------------

字符串装字节串:
字符串编码为字节码: '12abc'.encode(' ascii') ==> b'12abc'
数字或字符数组: bytes([1, 2,ord('1'), ord('2')]) ==> b'\x01\x0212'
16进制字符串: bytes().fromhex('010210') ==> b'\x01\x02\x10'
16进制字符串: bytes(map(ord,'\x01\x02\x31\x32')) ==> b'\x01\x0212'
16进制数组: bytes([0x01, 0x02, 0x31, 0x32]) ==> b'\x01\x0212'

====================

字节串转字符串:
字节码解码为字符串: bytes(b'\x31\x32\x61\x62').decode('ascii') ==> 12ab
字节出传16进制表示,夹带ascii: str(bytes(b'lx01\x0212'))[2:-1] ==> lx01\x0212
字节串转16进制表示, 固定两个字符表示: str(binascii.b2a_hex(b'\x01\x0212'))[2:-1] ==> 01023132

====================

三. 总结

总结起来,网络传输数据时,

  • 无论是字节传输还是二进制传输,传输速度是相同的,可以根据实际需求选择适合的数据格式进行传输。
  • 数据是以二进制的形式进行传输,但以字节为单位进行表示和计算传输速度更为常见和推荐。
文章来源:https://blog.csdn.net/qq_43030934/article/details/135017513
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。