首页 新闻 会员 周边

通讯协议的问题

0
悬赏园豆:100 [已解决问题] 解决于 2024-04-23 19:13



通过技术手段分析数据得出以下几组测试用例

请使用C# 写出两个函数packedEncode(字符串转Packed类型字节序列)与packedDecode(Packed类型字节序列转字符串),并使用函数计算补全以下表格内容。

梅卫军的主页 梅卫军 | 初学一级 | 园豆:14
提问于:2024-04-19 15:02
< >
分享
最佳答案
1

给你个python版本

from decimal import Decimal

class Decoder:
    def __init__(self):
        self.write_pos = 0
        self.read_pos = 0
        self.data = Decimal(0)

    def write_byte(self, data:int):
        self.data = self.data + Decimal(data) * pow(2, self.write_pos)
        self.write_pos += 8

    def write(self, data:str):
        data = reversed(data)
        for i in data:
            self.write_byte(ord(i))

    def read_byte(self):
        if self.read_pos >= self.write_pos: return None
        ret = int(self.data // pow(2,self.read_pos)) & 0x3F
        self.read_pos += 6

        if ret < 0x20: ret += 0x40

        return ret

    def read(self):
        data = []
        while True:
            byte = self.read_byte()
            if byte is None: break
            data += chr(byte)
        data = reversed(data)
        return ''.join(data)

decoder = Decoder()
decoder.write('\x31\x6b\x74\xCB\x0C\x60')
print('31 6b 74 CB 0C 60')
print('LV-4201')
print(decoder.read())
print()

decoder = Decoder()
decoder.write('\x31\x6b\x71\xCB\x3D\x35')
print('31 6b 71 CB 3D 35')
print('LV-12345')
print(decoder.read())
print()

decoder = Decoder()
decoder.write('\x31\x6b\x20\x82\x08\x20')
print('31 6b 20 82 08 20')
print('LV')
print(decoder.read())
print('')

decoder = Decoder()
decoder.write('\x3C\xB0\x31\xCB\x3D\x35')
ret = decoder.read()
print(ret)

31 6b 74 CB 0C 60
LV-4201
LV-4201

31 6b 71 CB 3D 35
LV-12345
LV-12345

31 6b 20 82 08 20
LV
LV,

OK@12345

收获园豆:100
www378660084 | 菜鸟二级 |园豆:319 | 2024-04-23 19:06

非常感谢

梅卫军 | 园豆:14 (初学一级) | 2024-04-23 19:12

另外想问一下,Encode有对应的代码吗?

梅卫军 | 园豆:14 (初学一级) | 2024-04-24 02:42

我尝试反转,发现不可以做反转,是不是有其他的路,就是说我输入LV-4201,应该输出31 6b 74 CB 0C 60的过程

梅卫军 | 园豆:14 (初学一级) | 2024-04-24 04:35

@梅卫军: 其实不用反转,大小端处理好就行了.

from decimal import Decimal

class Decoder:
    def __init__(self):
        self.write_pos = 0
        self.read_pos = 0
        self.data = Decimal(0)

    def write_byte(self, data:int):
        self.data = self.data * 256 + Decimal(data)
        self.write_pos += 8

    def write(self, data:str):
        for i in data:
            self.write_byte(ord(i))

    def read_byte(self):
        if self.read_pos >= self.write_pos: return None
        ret = int(self.data // pow(2,self.write_pos - self.read_pos - 6)) & 0x3F
        self.read_pos += 6

        if ret < 0x20: ret += 0x40

        return ret

    def read(self):
        data = []
        while True:
            byte = self.read_byte()
            if byte is None: break
            data += chr(byte)
        return ''.join(data)

decoder = Decoder()
decoder.write('\x31\x6b\x74\xCB\x0C\x60')
print('31 6b 74 CB 0C 60')
print('LV-4201')
print(decoder.data)
print(decoder.read())
print()

decoder = Decoder()
decoder.write('\x31\x6b\x71\xCB\x3D\x35')
print('31 6b 71 CB 3D 35')
print('LV-12345')
print(decoder.read())
print()

decoder = Decoder()
decoder.write('\x31\x6b\x20\x82\x08\x20')
print('31 6b 20 82 08 20')
print('LV')
print(decoder.read())
print('')

decoder = Decoder()
decoder.write('\x3C\xB0\x31\xCB\x3D\x35')
ret = decoder.read()
print(ret)
www378660084 | 园豆:319 (菜鸟二级) | 2024-04-24 15:53

@梅卫军: encode就是拿4个字节,不够4字节的,用空格补上,把每个字节的高2位去掉. 然后拼成3个字节. 注意大小端就行.decode也可以这么做,每次拿3个字节,每次取6bit,取4个,刚好4个字节. 主要是注意大小端

www378660084 | 园豆:319 (菜鸟二级) | 2024-04-24 15:56

@www378660084: 非常感谢,这块我不太熟悉,偏硬件了

梅卫军 | 园豆:14 (初学一级) | 2024-04-24 16:10

@梅卫军: 给你个通义灵码的答案,你也可以去问问:https://tongyi.aliyun.com/qianwen/
这是我提问的过程,你可以试试,根据回答调整提示,应该能得到你需要的:
用python把包含A到Z,数字和空格的字符串,每4个字符压缩成3个字节,字母减去0x40,不使用查表
字母只有大写,不需要压缩算法,加上这个条件,重新给出代码
上面代码没有把4个字符压缩成3个字节
解码时候,只有小于0x20,才需要加0x40

def compress(input_str):
    if(len(input_str) % 4 != 0):
        input_str += ' '*(4 - len(input_str) % 4)

    # 字符映射:大写字母减去0x40,数字和空格保持不变
    encoded_str = ''.join(chr(ord(c) - 0x40) if ord(c)>= 0x40 else c for c in input_str)
    # 分块压缩:每4个字符压缩为3个字节
    compressed_bytes = bytearray()
    for i in range(0, len(encoded_str), 4):
        chunk = encoded_str[i:i+4]
        byte1 = (ord(chunk[0]) << 2) | (ord(chunk[1]) >> 4)
        byte2 = ((ord(chunk[1]) & 0xF) << 4) | (ord(chunk[2]) >> 2)
        byte3 = ((ord(chunk[2]) & 0x3) << 6) | ord(chunk[3])
        compressed_bytes.extend([byte1, byte2, byte3])

    return compressed_bytes
def decompress(compressed_bytes):
    # 反向解压:每3个字节解压缩为4个字符
    decompressed_str = ''
    for i in range(0, len(compressed_bytes), 3):
        chunk = compressed_bytes[i:i+3]
        char1 = chr((chunk[0] >> 2) + (0x40 if (chunk[0] >> 2) < 0x20 else 0))
        char2 = chr(((chunk[0] & 0x3) << 4) | (chunk[1] >> 4) + (0x40 if (((chunk[0] & 0x3) << 4) | (chunk[1] >> 4)) < 0x20 else 0))
        char3 = chr(((chunk[1] & 0xF) << 2) | (chunk[2] >> 6) + (0x40 if (((chunk[1] & 0xF) << 2) | (chunk[2] >> 6)) < 0x20 else 0))
        char4 = chr(chunk[2] & 0x3F + (0x40 if (chunk[2] & 0x3F) < 0x20 else 0))
        decompressed_str += char1 + char2 + char3 + char4

    return decompressed_str

input_str = "LV-4201"
print(f"Original: {input_str}")

compressed = compress(input_str)
print(f"Compressed: {compressed.hex()}")

decompressed = decompress(compressed)
print(f"Decompressed: {decompressed}")


#Original: LV-4201
#Compressed: 316b74cb0c60
#Decompressed: LV-4201
www378660084 | 园豆:319 (菜鸟二级) | 2024-04-24 16:16

@www378660084: 好的,非常感谢!

梅卫军 | 园豆:14 (初学一级) | 2024-04-24 16:17
其他回答(2)
0

https://blog.csdn.net/weixin_53403301/article/details/127887607 ASCII压缩
https://blog.csdn.net/weixin_53403301/article/details/130367350
https://zhuanlan.zhihu.com/p/659810718 这个可以参考一下
你应该把协议名说出来,这样很容易找到问题的答案,百度简单很多,你光搜索协议,这个太多了,不好定位。

wangjinming | 园豆:571 (小虾三级) | 2024-04-22 17:37

谢谢,这也是别人给的题目,就是因为没有额外的信息,所以才比较难搞

支持(0) 反对(0) 梅卫军 | 园豆:14 (初学一级) | 2024-04-24 04:34
0

下面的3C-B0-31-CB-3D-35 应该是是OK12345吧

jiajinzhao | 园豆:458 (菜鸟二级) | 2024-04-23 12:25

不好意思,我打错了

怎么做到的,能告知吗?

支持(0) 反对(0) 梅卫军 | 园豆:14 (初学一级) | 2024-04-23 17:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册