/ Published in: C#

For those having trouble with encoding and decoding bencode, here is something to help you.
Expand | Embed | Plain Text
Copy this code and paste it in your HTML
/***** * Encoding usage: * * new BDictionary() * { * {"Some Key", "Some Value"}, * {"Another Key", 42} * }.ToBencodedString(); * * Decoding usage: * * BencodeDecoder.Decode("d8:Some Key10:Some Value13:Another Valuei42ee"); * * Feel free to use it. * More info about Bencoding at http://wiki.theory.org/BitTorrentSpecification#bencoding * * Originally posted at http://snipplr.com/view/37790/ by SuprDewd. * */ usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; namespace Bencoding { /// <summary> /// A class used for decoding Bencoding. /// </summary> publicstaticclass BencodeDecoder { /// <summary> /// Decodes the string. /// </summary> /// <param name="bencodedString">The bencoded string.</param> /// <returns>An array of root elements.</returns> publicstatic BElement[] Decode(string bencodedString) { int index =0; try { if(bencodedString ==null)returnnull; while(bencodedString.Length> index) { rootElements.Add(ReadElement(ref bencodedString, ref index)); } return rootElements.ToArray(); } catch(BencodingException){throw;} catch(Exception e){throw Error(e);} } privatestatic BElement ReadElement(refstring bencodedString, refint index) { switch(bencodedString[index]) { case'0': case'1': case'2': case'3': case'4': case'5': case'6': case'7': case'8': case'9':return ReadString(ref bencodedString, ref index); case'i':return ReadInteger(ref bencodedString, ref index); case'l':return ReadList(ref bencodedString, ref index); case'd':return ReadDictionary(ref bencodedString, ref index); default:throw Error(); } } privatestatic BDictionary ReadDictionary(refstring bencodedString, refint index) { index++; try { while(bencodedString[index]!='e') { BString K = ReadString(ref bencodedString, ref index); BElement V = ReadElement(ref bencodedString, ref index); dict.Add(K, V); } } catch(BencodingException){throw;} catch(Exception e){throw Error(e);} index++; return dict; } privatestatic BList ReadList(refstring bencodedString, refint index) { index++; try { while(bencodedString[index]!='e') { lst.Add(ReadElement(ref bencodedString, ref index)); } } catch(BencodingException){throw;} catch(Exception e){throw Error(e);} index++; return lst; } privatestatic BInteger ReadInteger(refstring bencodedString, refint index) { index++; int end = bencodedString.IndexOf('e', index); if(end ==-1)throw Error(); long integer; try { integer = Convert.ToInt64(bencodedString.Substring(index, end - index)); index = end +1; } catch(Exception e){throw Error(e);} } privatestatic BString ReadString(refstring bencodedString, refint index) { int length, colon; try { colon = bencodedString.IndexOf(':', index); if(colon ==-1)throw Error(); length = Convert.ToInt32(bencodedString.Substring(index, colon - index)); } catch(Exception e){throw Error(e);} index = colon +1; int tmpIndex = index; index += length; try { } catch(Exception e){throw Error(e);} } privatestatic Exception Error(Exception e) { } privatestatic Exception Error() { } } /// <summary> /// An interface for bencoded elements. /// </summary> publicinterface BElement { /// <summary> /// Generates the bencoded equivalent of the element. /// </summary> /// <returns>The bencoded equivalent of the element.</returns> string ToBencodedString(); /// <summary> /// Generates the bencoded equivalent of the element. /// </summary> /// <param name="u">The StringBuilder to append to.</param> /// <returns>The bencoded equivalent of the element.</returns> StringBuilder ToBencodedString(StringBuilder u); } /// <summary> /// A bencode integer. /// </summary> publicclass BInteger : BElement, IComparable<BInteger> { /// <summary> /// Allows you to set an integer to a BInteger. /// </summary> /// <param name="i">The integer.</param> /// <returns>The BInteger.</returns> publicstaticimplicitoperator BInteger(int i) { } /// <summary> /// The value of the bencoded integer. /// </summary> publiclongValue{get;set;} /// <summary> /// The main constructor. /// </summary> /// <param name="value">The value of the bencoded integer.</param> public BInteger(longvalue) { this.Value=value; } /// <summary> /// Generates the bencoded equivalent of the integer. /// </summary> /// <returns>The bencoded equivalent of the integer.</returns> publicstring ToBencodedString() { } /// <summary> /// Generates the bencoded equivalent of the integer. /// </summary> /// <returns>The bencoded equivalent of the integer.</returns> public StringBuilder ToBencodedString(StringBuilder u) { else u.Append('i'); return u.Append(Value.ToString()).Append('e'); } /// <see cref="Object.GetHashCode()"/> publicoverrideint GetHashCode() { returnthis.Value.GetHashCode(); } /// <summary> /// Int32.Equals(object) /// </summary> publicoverridebool Equals(object obj) { try { returnthis.Value.Equals(((BInteger)obj).Value); } catch{returnfalse;} } /// <see cref="Object.ToString()"/> publicoverridestring ToString() { returnthis.Value.ToString(); } /// <see cref="IComparable.CompareTo(object)"/> publicint CompareTo(BInteger other) { returnthis.Value.CompareTo(other.Value); } } /// <summary> /// A bencode string. /// </summary> publicclass BString : BElement, IComparable<BString> { /// <summary> /// Allows you to set a string to a BString. /// </summary> /// <param name="s">The string.</param> /// <returns>The BString.</returns> publicstaticimplicitoperator BString(string s) { } /// <summary> /// The value of the bencoded integer. /// </summary> publicstringValue{get;set;} /// <summary> /// The main constructor. /// </summary> /// <param name="value"></param> public BString(stringvalue) { this.Value=value; } /// <summary> /// Generates the bencoded equivalent of the string. /// </summary> /// <returns>The bencoded equivalent of the string.</returns> publicstring ToBencodedString() { } /// <summary> /// Generates the bencoded equivalent of the string. /// </summary> /// <param name="u">The StringBuilder to append to.</param> /// <returns>The bencoded equivalent of the string.</returns> public StringBuilder ToBencodedString(StringBuilder u) { else u.Append(this.Value.Length); return u.Append(':').Append(this.Value); } /// <see cref="Object.GetHashCode()"/> publicoverrideint GetHashCode() { returnthis.Value.GetHashCode(); } /// <summary> /// String.Equals(object) /// </summary> publicoverridebool Equals(object obj) { try { returnthis.Value.Equals(((BString)obj).Value); } catch{returnfalse;} } /// <see cref="Object.ToString()"/> publicoverridestring ToString() { returnthis.Value.ToString(); } /// <see cref="IComparable.CompareTo(Object)"/> publicint CompareTo(BString other) { returnthis.Value.CompareTo(other.Value); } } /// <summary> /// A bencode list. /// </summary> publicclass BList : List<BElement>, BElement { /// <summary> /// Generates the bencoded equivalent of the list. /// </summary> /// <returns>The bencoded equivalent of the list.</returns> publicstring ToBencodedString() { } /// <summary> /// Generates the bencoded equivalent of the list. /// </summary> /// <param name="u">The StringBuilder to append to.</param> /// <returns>The bencoded equivalent of the list.</returns> public StringBuilder ToBencodedString(StringBuilder u) { else u.Append('l'); foreach(BElement element inbase.ToArray()) { element.ToBencodedString(u); } return u.Append('e'); } /// <summary> /// Adds the specified value to the list. /// </summary> /// <param name="value">The specified value.</param> publicvoidAdd(stringvalue) { } /// <summary> /// Adds the specified value to the list. /// </summary> /// <param name="value">The specified value.</param> publicvoidAdd(intvalue) { } } /// <summary> /// A bencode dictionary. /// </summary> publicclass BDictionary : SortedDictionary<BString, BElement>, BElement { /// <summary> /// Generates the bencoded equivalent of the dictionary. /// </summary> /// <returns>The bencoded equivalent of the dictionary.</returns> publicstring ToBencodedString() { } /// <summary> /// Generates the bencoded equivalent of the dictionary. /// </summary> /// <param name="u">The StringBuilder to append to.</param> /// <returns>The bencoded equivalent of the dictionary.</returns> public StringBuilder ToBencodedString(StringBuilder u) { else u.Append('d'); for(int i =0; i <base.Count; i++) { base.Keys.ElementAt(i).ToBencodedString(u); base.Values.ElementAt(i).ToBencodedString(u); } return u.Append('e'); } /// <summary> /// Adds the specified key-value pair to the dictionary. /// </summary> /// <param name="key">The specified key.</param> /// <param name="value">The specified value.</param> publicvoidAdd(string key, BElement value) { } /// <summary> /// Adds the specified key-value pair to the dictionary. /// </summary> /// <param name="key">The specified key.</param> /// <param name="value">The specified value.</param> publicvoidAdd(string key, stringvalue) { } /// <summary> /// Adds the specified key-value pair to the dictionary. /// </summary> /// <param name="key">The specified key.</param> /// <param name="value">The specified value.</param> publicvoidAdd(string key, intvalue) { } /// <summary> /// Gets or sets the value assosiated with the specified key. /// </summary> /// <param name="key">The key of the value to get or set.</param> /// <returns>The value assosiated with the specified key.</returns> public BElement this[string key] { get { } set { } } } /// <summary> /// A bencoding exception. /// </summary> publicclass BencodingException : FormatException { /// <summary> /// Creates a new BencodingException. /// </summary> public BencodingException(){} /// <summary> /// Creates a new BencodingException. /// </summary> /// <param name="message">The message.</param> public BencodingException(string message):base(message){} /// <summary> /// Creates a new BencodingException. /// </summary> /// <param name="message">The message.</param> /// <param name="inner">The inner exception.</param> public BencodingException(string message, Exception inner):base(message, inner){} } /// <summary> /// A class with extension methods for use with Bencoding. /// </summary> publicstaticclass BencodingExtensions { /// <summary> /// Decode the current instance. /// </summary> /// <param name="s">The current instance.</param> /// <returns>The root elements of the decoded string.</returns> publicstatic BElement[] BDecode(thisstring s) { return BencodeDecoder.Decode(s); } } }
Comments

You need to login to post a comment.