Greasy Fork is available in English.

Bencode encoder/decoder

Module for encoding/decoding Bencoded data

2015-10-12 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

بۇ قوليازمىنى بىۋاسىتە قاچىلاشقا بولمايدۇ. بۇ باشقا قوليازمىلارنىڭ ئىشلىتىشى ئۈچۈن تەمىنلەنگەن ئامبار بولۇپ، ئىشلىتىش ئۈچۈن مېتا كۆرسەتمىسىگە قىستۇرىدىغان كود: // @require https://update.greatest.deepsurf.us/scripts/13016/79773/Bencode%20encoderdecoder.js

  1. // ==UserScript==
  2. // @name Bencode encoder/decoder
  3. // @description Module for encoding/decoding Bencoded data
  4. // @version 1.0
  5. // ==/UserScript==
  6.  
  7. var bencode = (function() {
  8. "use strict";
  9.  
  10. // Encoding functions
  11. var encode = function (value) {
  12. // Type
  13. var t = typeof(value);
  14.  
  15. // Number
  16. if (t == "number") return encode_int(Math.floor(value));
  17. // String
  18. if (t == "string") return encode_string(value);
  19. // Array
  20. if (Array.isArray(value)) return encode_list(value);
  21. // Dict
  22. return encode_dict(value);
  23. };
  24.  
  25. var encode_int = function (value) {
  26. return "i" + value + "e";
  27. };
  28. var encode_string = function (value) {
  29. return "" + value.length + ":" + value;
  30. };
  31. var encode_list = function (value) {
  32. var str = [ "l" ],
  33. i;
  34.  
  35. // List values
  36. for (i = 0; i < value.length; ++i) {
  37. str.push(encode(value[i]));
  38. }
  39.  
  40. // End
  41. str.push("e");
  42. return str.join("");
  43. };
  44. var encode_dict = function (value) {
  45. var str = [ "d" ],
  46. keys = [],
  47. i;
  48.  
  49. // Get and sort keys
  50. for (i in value) keys.push(i);
  51. keys.sort();
  52.  
  53. // Push values
  54. for (i = 0; i < keys.length; ++i) {
  55. str.push(encode_string(keys[i]));
  56. str.push(encode(value[keys[i]]));
  57. }
  58.  
  59. // End
  60. str.push("e");
  61. return str.join("");
  62. };
  63.  
  64.  
  65.  
  66. // Decoding class
  67. var Decoder = function () {
  68. this.pos = 0;
  69. };
  70.  
  71. Decoder.prototype = {
  72. constructor: Decoder,
  73.  
  74. decode: function (str) {
  75. // Errors
  76. var k = str[this.pos];
  77. if (!(k in decode_generic)) throw "Invalid format";
  78.  
  79. // Call
  80. return decode_generic[k].call(this, str);
  81. },
  82. decode_int: function (str) {
  83. // Skip the "i" prefix
  84. ++this.pos;
  85.  
  86. var end = str.indexOf("e", this.pos),
  87. value;
  88.  
  89. // No end
  90. if (end < 0) throw "Invalid format";
  91.  
  92. // Assume proper number format
  93. value = parseInt(str.substr(this.pos, end - this.pos), 10);
  94.  
  95. // Done
  96. this.pos = end + 1;
  97. return value;
  98. },
  99. decode_string: function (str) {
  100. var delim = str.indexOf(":", this.pos),
  101. length, value;
  102.  
  103. // No end
  104. if (delim < 0) throw "Invalid format";
  105.  
  106. // Assume proper number format
  107. length = parseInt(str.substr(this.pos, delim - this.pos), 10);
  108. value = str.substr(delim + 1, length);
  109.  
  110. // Done
  111. this.pos = delim + length + 1;
  112. return value;
  113. },
  114. decode_list: function (str) {
  115. // Skip the "l" prefix
  116. ++this.pos;
  117.  
  118. // Read list
  119. var list = [],
  120. value;
  121.  
  122. // Loop until end or exception
  123. while (str[this.pos] != "e") {
  124. value = this.decode(str); // this throws errors if str[this.pos] is out of bounds
  125. list.push(value);
  126. }
  127.  
  128. // Done; skip "e" suffix
  129. ++this.pos;
  130. return list;
  131. },
  132. decode_dict: function (str) {
  133. // Skip the "d" prefix
  134. ++this.pos;
  135.  
  136. // Read dict
  137. var dict = {},
  138. key, value;
  139.  
  140. // Loop until end or exception
  141. while (str[this.pos] != "e") {
  142. key = this.decode_string(str);
  143. value = this.decode(str); // this throws errors if str[this.pos] is out of bounds
  144. dict[key] = value;
  145. }
  146.  
  147. // Done; skip "e" suffix
  148. ++this.pos;
  149. return dict;
  150. }
  151. };
  152.  
  153. // Generic decode functions
  154. var decode_generic = {
  155. "l": Decoder.prototype.decode_list,
  156. "d": Decoder.prototype.decode_dict,
  157. "i": Decoder.prototype.decode_int,
  158. },
  159. i;
  160. for (i = 0; i < 10; ++i) decode_generic[i.toString()] = Decoder.prototype.decode_string;
  161.  
  162.  
  163.  
  164. // Encode/decode functions
  165. return {
  166. /**
  167. encode: function (obj)
  168. Encodes an object into a Bencode'd string
  169. @param obj
  170. The object to encode
  171. This should only be one of the following:
  172. string
  173. number (floats are floor'd to integers)
  174. array (containing things only from this list)
  175. object (containing things only from this list)
  176. Strings should be encoded in some way such that each character is in the range [0,255]
  177. @return
  178. A string representing the object
  179. */
  180. encode: encode,
  181. /**
  182. decode: function (str)
  183. Decodes a Bencode'd string back into its original type
  184. @param str
  185. The string to decode
  186. @return
  187. The original object represented by str
  188. @throws
  189. Any one of the following self-explanatory strings
  190. "Invalid format"
  191. "Invalid string"
  192. "Invalid int"
  193. */
  194. decode: function (str) {
  195. // Create a decoder and call
  196. return (new Decoder()).decode(str);
  197. },
  198. };
  199.  
  200. })();