Bencode encoder/decoder

Module for encoding/decoding Bencoded data

Ezt a szkriptet nem ajánlott közvetlenül telepíteni. Ez egy könyvtár más szkriptek számára, amik tartalmazzák a // @require https://update.greatest.deepsurf.us/scripts/13016/79776/Bencode%20encoderdecoder.js hivatkozást.

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