经常与TCP/IP协议族打交道,免不了要画各种协议报文的纯文本结构图。为何需要纯文本结构图?想想在工程的源代码中,您能贴张jpeg或png的图片上去?
示范代码以输出 IP 包头为例, 使用python 2.7 编写(Python 3 应该也能运行)。本程序还可以用来画类似结构的表格图,再次抛砖引玉,欢迎大家使用交流。
代码
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- '''''
- Copyright (c) 2014, Thomas Hu. All rights reserved.
- Created on 2014-8-3
- @author: Thomas Hu
- @email : thomashtq#163.com
- '''
- import math
- from string import ljust, rjust, center
- def format_protocol(head_list, just_type):
- just_dict = {"ljust": ljust,
- "rjust": rjust,
- "center": center,
- }
- just_func = just_dict.get(just_type.lower(), center)
- vchar = "|"
- head = vchar
- width = 2
- max_key = 0
- # Get the maximum width
- for item in head_list:
- tmp = math.ceil(float(len(item[0])) / item[1])
- if tmp > width:
- width = int(tmp)
- if len(item[0]) > max_key:
- max_key = len(item[0])
- for i in range(32):
- head += " "*(width - len(str(i))) + str(i) + vchar
- hline = vchar + "-" *(len(head) - 2) + vchar
- print(head)
- print(hline)
- index = 0
- line = vchar
- # Print protocol head
- for item in head_list:
- line += item[0].center(item[1] * (width + 1) - 1, " ") + vchar
- index += item[1]
- if index % 32 == 0:
- print(line)
- print(hline)
- line = vchar
- # Print protocol description
- print("\r\nThe protocol head items description are as follows:")
- for item in head_list:
- print("%s : %s"%(just_func(item[0], max_key, " "), item[2]))
- if __name__ == '__main__':
- head_list = [("Ver", 4, "Protocol version"),
- ("Head", 4, "Head length(in bytes)"),
- ("TOS", 8, "Type of service"),
- ("Total Length", 16, "The total length of IP packet(in bytes)"),
- ("ID", 16, "The identification of packet"),
- ("Flag", 3, "The flag"),
- ("Offset", 13, "The offset"),
- ("TTL", 8, "Time to live"),
- ("Proto", 8, "The protocol id"),
- ("Checksum", 16, "The head check sum"),
- ("Source Address", 32, "The source IP address"),
- ("Destination Address", 32, "The destination IP address"),
- ("Opitons(if has)", 32, "The options block, if has that"),
- ("Data", 32, "The data block of IP packet"),
- ]
- format_protocol(head_list, "ljust")