zoukankan      html  css  js  c++  java
  • BEncoding的编码与解码

    BEncoding的编码与解码

     

    1. BEncoding规则

            BEncoding是BitTorrent用在传输数据结构的编码方式,我们最熟悉的“种子”文件,它里面的元数据就是 BEncoding 过的字典表。虽然比用纯二进制编码效率低,但由于结构简单而且不受字节存储顺序影响(所有数字以十进制编码,不存在大端小端的问题)——这对于跨平台性非常重要。而且具有较好的灵活性,即使存在故障的字典键,只要将其忽略并更换新的就能兼容补充,更多介绍见维基百科

            这种编码方式支持四种类型的数据:string, int, Dictionary<string, object>, List<object>,各自的编码规则如下:

    1.1 string类型

            string类型的编码格式为[length]:[string]。以字符串的长度开头,加一个冒号,并以字符串内容结束。示例:

    "abc" => 3:abc

    1.2 int类型

            int类型的编码格式为i[int]e。以i开头,加上数字,以e结尾。 示例:

    123 => i123e

    1.3 List<object>类型

            List<object>类型的编码格式为l[object]e。以l开头,加上列表中各个元素的编码(元素的类型同样为BEncoding支持的类型),以e结尾。 示例:

    List<"abc", 123> => l3:abci123ee

    1.4 Dictionary<string, object>类型

            Dictionary<string, object>类型的编码格式为d[Key-Value Pair]e。以d开头,加上字典中每个键值对的编码,以e结尾。示例:

    Dictionary<{"name":"create chen"},{"age":23}> => d4:name11:create chen3:agei23ee

            感兴趣的朋友可以自己写着玩玩 微笑

    2. BEncoding编码

    2.1 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    public static string Encode(object obj)
    {
        var sb = new StringBuilder();
        if(obj is Dictionary<string,object>)
        {
            var parseObj = obj as Dictionary<string, object>;
            sb.Append("d");
            foreach (var o in parseObj)
            {
                sb.AppendFormat("{0}:{1}{2}", o.Key.Length,o.Key, Encode(o.Value));
            }
            sb.Append("e");
        }
        if ((obj as int?) != null)
        {
            var parseObj = (int) obj;
            sb.AppendFormat("i{0}e", parseObj);
        }
        if (obj is List<object>)
        {
            var parseObj = obj as List<object>;
            sb.Append("l");
            foreach (var o in parseObj)
            {
                sb.Append(Encode(o));
            }
            sb.Append("e");
        }
        if (obj is string)
        {
            var parseObj = obj as string;
            sb.AppendFormat("{0}:{1}", parseObj.Length, parseObj);
        }
        return sb.ToString();
    }

    2.2 测试对象:

    1
    2
    3
    4
    5
    6
    7
    var obj = new Dictionary<string, Object>
        {
            {"nick", "Create Chen"},
            {"age", 23},
            {"blog","http://www.cnblogs.com/technology"},
            {"hobbies", new List<object> {"Coding", "Basketball"}}
        };

    2.3 输出:

    d4:nick11:Create Chen3:agei23e4:blog33:http://www.cnblogs.com/technology7:hobbiesl6:Coding10:Basketballee

    3. BEncoding解码

    3.1 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    public static object Decode(string s)
    {
        return DecodeObject(s, ref _index, EncodeState.Value);
    }
     
    private enum EncodeState
    {
        Key,
        Value
    }
     
    private static int _index;
     
    private static object DecodeObject(string str,ref int index, EncodeState state)
    {
        var obj = new Dictionary<string, object>();
     
        var c = str[index];
        while (c != 'e')
        {
            if (c == 'd')//字典类型
            {
                index++;
                return DecodeObject(str, ref index,EncodeState.Key);
            }
            if (c == 'i')//数字类型
            {
                var value = "";
                index++; c = str[index];
                while (c != 'e')
                {
                    value += c.ToString(CultureInfo.InvariantCulture);
                    index++;
                    c = str[index];
                }
                return Convert.ToInt32(value);
            }
            if (c == 'l')//列表类型
            {
                index++;
                var value = new List<object>();
                while (str[index]!='e')
                {
                    value.Add(DecodeObject(str, ref index, EncodeState.Value));
                    index++;
                }
                return value;
            }
            if ('0' < c && c <= '9') //字符串类型
            {
                string strLength = "";
                while (c != ':')
                {
                    strLength += c.ToString(CultureInfo.InvariantCulture);
                    c = str[++index];
                }
                var length = Convert.ToInt32(strLength);
                var strContent = "";
                for (int i = 0; i < length; i++)
                {
                    strContent += str[index + 1].ToString(CultureInfo.InvariantCulture);
                    index++;
                }
                if (state == EncodeState.Value)
                {
                    return strContent;
                }
                index++;
                obj.Add(strContent, DecodeObject(str, ref index, EncodeState.Value));
                state = EncodeState.Key;
                index++;
            }
            c = str[index];
        }
        return obj;
    }

    3.2 测试对象:

    d4:nick11:Create Chen3:agei23e4:blog33:http://www.cnblogs.com/technology7:hobbiesl6:Coding10:Basketballee

    3.3 还原类型

    4. 代码下载

            

    本文链接:http://www.cnblogs.com/technology/p/BEncoding.html

  • 相关阅读:
    POJ 1887 Testing the CATCHER
    HDU 3374 String Problem
    HDU 2609 How many
    POJ 1509 Glass Beads
    POJ 1458 Common Subsequence
    POJ 1159 Palindrome
    POJ 1056 IMMEDIATE DECODABILITY
    POJ 3080 Blue Jeans
    POJ 1200 Crazy Search
    软件体系结构的艺术阅读笔记1
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3348714.html
Copyright © 2011-2022 走看看