Интернет на магнитах 4 — Делим магнит на части

    В своих статьях «интернет на магнитах» я предлагал публиковать универсальные магниты с помощью которых можно скачать файл из любой p2p сети (Gnutella, Gnutella2, Edonkey2000, DirectConnect, BitTorrent). Их можно получить, либо с помощью программы rhash, либо смешав разные магниты и ссылки на файл на странице сервиса Magnet Converter. Но есть проблема в том что не многие клиенты для p2p сетей лояльно относятся к произвольному порядку параметров в магните. Я решил написать скрипт который исправляет эту ситуацию на всех страницах интернета.

    Под катом вас ждёт JavaScript код с комментариями и тестовая ссылка.

    Итак. Создаём папку «magnet-converter» в которой будут файлы:

    Файл "manifest.json":


    Чтоб скрипт можно было подключить как расширение Chrome.

    { 
      "manifest_version": 2,
      "name": "Magnet Splitter",
      "description": "Splits universal magnet links to suitable for different p2p clients",
      "version": "1.1",
      "content_scripts": [
        {
          "matches": [ "http://*/*", "https://*/*" ],
          "js": [ "insert.js" ],
    	  "run_at": "document_end"
        }
      ],
      "web_accessible_resources": [
        "magnet-converter.user.js"
      ]
    } 
    

    Файл "insert.js":


    Вставляем скрипт на страницу.

    var script   = document.createElement('script');
    script.type  = 'text/javascript';
    script.src   = chrome.extension.getURL("magnet-converter.user.js");
    script.async = 1;
    document.head.appendChild(script);

    Файл "magnet-converter.user.js"


    Сам скрипт. Его можно подключить как пользовательский скрипт Greasemonkey и Tampermonkey. Также владелец сайта который публикует универсальные магниты может подключить его к своим страницам.

    // ==UserScript==
    // @name Magnet Splitter
    // @description Splits universal magnet links to suitable for different p2p clients.
    // @author ivan386
    // @license MIT
    // @version 1.1
    // @run-at document-end
    // @include http://*/*
    // @include https://*/*
    // ==/UserScript==
    
    javascript:
    
    /*

    Букмарклет



    Этот скрипт можно скопировать и сохранить в закладки (от «javascript:» до «void();» включительно).

    Для корректной работы скрипта в букмарклете:
    1. используем только внутристрочные комментарии
    2. завершаем инструкции точкой с запятой
    3. ставим пробел после else в конце строки
    */
    (function() {
        'use strict';
    
    
    	function try_decode(data){
    		try{
    			data = decodeURIComponent(data);
    		}catch(e){console.error(e)}
    		return data;
    	}
    
    
    
    /*
    Разбираем магнит на части
    */
    
    	function detect_ipfs_hash(url, file)
    	{
    		url.replace(/\/ipfs\/([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+)/,function(all, hash){
    			if (!file.hash) file.hash = {};
    			file.hash.ipfs = hash;
    		});
    		return;
    	}
    
    	function parse_urn(urn_name, urn_data, file)
    	{
    		if (!file.hash) file.hash = {};
    		switch (urn_name){
    			case "urn:sha1:": /* sha1 хеш  файла (Base32) */
    				file.hash.sha1 = urn_data;
    			break;
    			case "urn:ed2k:": /* ed2k хеш  файла (Hex) */
    			case "urn:ed2khash:":
    				file.hash.ed2k = urn_data;
    			break;
    			case "urn:aich:": /* Advanced Intelligent Corruption  */
    				file.hash.aich = urn_data;
    			break;
    			case "urn:btih:": /* BitTorrent Info Hash (Hex, Base32) */
    				if (urn_data.length < 40)
    					file.hash.btih = base32_to_hex(urn_data);
    				else 
    					file.hash.btih = urn_data;
    			break;
    			case "urn:ipfs:": /* InterPlanetary File System мультихеш */
    				file.hash.ipfs = urn_data;
    			break;
    			case "urn:tree:tiger:": /* Tiger Tree Hash (TTH) файла (Base32) */
    				file.hash.tree_tiger = urn_data;
    			break;
    			case "urn:bitprint:": /* [SHA1].[TTH] (Base32) */
    				var sha1_tth = urn_data.split(".");
    				if (sha1_tth && sha1_tth.length == 2){
    					file.hash.sha1 = sha1_tth[0];
    					file.hash.tree_tiger = sha1_tth[1];
    					file.hash.bitprint = urn_data;
    				};
    			break;
    			default: /* другие идентификаторы тоже сохраняем */
    				if (!file.urns) file.urns = [];
    				file.urns.push(urn_name+urn_data);
    		}
    	}
    	
    	function parse_magnet(params, file){
    		if (!file) file = {};
    		params.replace(/([a-z0-9\.]+)=((([a-z0-9\.]+:)*)([^&]+))&?/gmi,
    		function(all, name, data, urn, _, urn_data){
    			data = try_decode(data);
    			switch (name){
    				case "dn": /* (Display Name) — имя файла. */
    					file.name = data;
    					break;
    				case "xl": /* (eXact Length) — размер файла в байтах. */
    					file.size = data;
    					break;
    				case "br": /* Битрейт - скорость последовательной загрузки файла для его воспроизведения. */
    					file.bitrate = data;
    					break;
    				case "tr": /* (TRacker) — адрес трекера для BitTorrent клиентов. */
    					if (!file.trackers) file.trackers = [];
    					file.trackers.push(data);
    					break;
    				case "mt":	
    					file.collection = file.collection || [];
    					file.collection.push(data);
    					break;
    				case "x.do": /* Ссылка на страницу описания файла. */
    					if (!file.description_url) file.description_url = [];
    					file.description_url.push(data);
    					break;
    				case "fl": /* Ссылка на торрент файл. */
    					if (!file.torrent_file_url) file.torrent_file_url = [];
    					file.torrent_file_url.push(data);
    					break;
    				case "as": /* (Acceptable Source) — веб-ссылка на файл в Интернете. */
    				case "ws": /* Web Seed - прямая ссылка на файл или каталог для загрузки. */
    					if (!file.url) file.url = [];
    					file.url.push(data);
    					detect_ipfs_hash(data, file);
    					break;
    				case "xs": /* (eXact Source) — ссылка на источник файла в P2P сети. */
    					if (!file.xurl) file.xurl = [];
    					file.xurl.push(data);
    					detect_ipfs_hash(data, file);
    					break;
    				case "xt": /* URN, содержащий хеш */
    					parse_urn(urn, urn_data, file);
    					break;
    				case "x.ed2k.p":
    					(file.hash_list = file.hash_list || {}).ed2k = data.split(":");
    					break;
    			}
    		});
    		return file;
    	}
    
    
     
    /*

    Здесь происходит сборка магнита для торрента



    Торрент клиенту нужен прежде всего bittorrent info hash (btih).
    Он следует первым и обязателен для этого типа магнита.

    Пример магнита:
    magnet:?xt=urn:btih:16253d9beb0df49fe30bacc62ea10ba63939f0f8&dn=ruwiki-20141114-pages-meta-current.xml.bz2&tr=http%3A%2F%2Furl2torrent.net%3A6970%2Fannounce&ws=http%3A%2F%2Fdumps.wikimedia.org%2Fruwiki%2F20141114%2Fruwiki-20141114-pages-meta-current.xml.bz2&fl=http://torcache.net/torrent/16253D9BEB0DF49FE30BACC62EA10BA63939F0F8.torrent

    */
    	function torrent_magnet(file){
    		var magnet = ["magnet:?"];
    		if (file && file.hash && file.hash.btih) {
    			magnet.push("xt=urn:btih:");
    			magnet.push(encodeURIComponent(file.hash.btih));
    		}else return undefined;
    		if (file.name) {
    			magnet.push("&dn=");
    			magnet.push(encodeURIComponent(file.name));
    		}
    		if (file.trackers) {
    			for (var i=0; i < file.trackers.length; i++){
    				magnet.push("&tr=");
    				magnet.push(encodeURIComponent(file.trackers[i]));
    			}
    		}
    		if (file.url){
    			for (var i=0; i < file.url.length; i++){
    				magnet.push("&ws=");
    				magnet.push(encodeURIComponent(file.url[i]));
    			}
    		}
    		if (file.torrent_file_url){
    			for (var i=0; i < file.torrent_file_url.length; i++){
    				magnet.push("&fl=");
    				magnet.push(file.torrent_file_url[i]);
    			}
    		}
    		return magnet.join("");
    	}
    
    
    
    /*

    Эта функция собирает магнит для DirectConnect(DC++) клиентов.



    Для них обязателен tree tiger hash(TTH). Некоторые клиенты понимают и urn:bitprint в котором также содержится TTH но urn:tree:tiger: должны понимать все.
    Если не будет остальных параметров DC++ откроет окно поиска файла по TTH.

    Пример магнита:
    magnet:?xt=urn:tree:tiger:JNOANHGPELY63I2OMSPQ3J73AS2P4AWB5MTBJCQ&xl=2981763794&dn=ruwiki-20141114-pages-meta-current.xml.bz2&xs=http://cache.freebase.be/u24iyrp3wtlry5kjh7sacblft2lam62u&x.do=https%3A%2F%2Fdumps.wikimedia.org%2Fruwiki%2F20141114%2F&xs=dchub://allavtovo.ru

    */
    	function dc_magnet(file){
    		var magnet = ["magnet:?"];
    		if (file && file.hash && file.hash.tree_tiger) {
    			magnet.push("xt=urn:tree:tiger:");
    			magnet.push(file.hash.tree_tiger);
    		}else return;
    		if (file.size) {
    			magnet.push("&xl=");
    			magnet.push(encodeURIComponent(file.size));
    		}
    		if (file.name) {
    			magnet.push("&dn=");
    			magnet.push(encodeURIComponent(file.name));
    		}
    		if (file.xurl){
    			for (var i=0; i < file.xurl.length; i++){
    				magnet.push("&xs=");
    				magnet.push(file.xurl[i]);
    			}
    		}
    		if (file.description_url){
    			for (var i=0; i < file.description_url.length; i++){
    				magnet.push("&x.do=");
    				magnet.push(encodeURIComponent(file.description_url[i]));
    			}
    		}
    		return magnet.join("");
    	}
    
    
    
    /*

    Здесь собирается ed2k ссылка.



    На данный момент магниты из Edonkey2000 клиентов понимал только aMule. Поэтому мы собираем стандартную для этой сети ed2k ссылку.

    Пример ссылки:
    ed2k://|file|ruwiki-20141114-pages-meta-current.xml.bz2|2981763794|0218392e98873112284de6913efee0df|s=http%3A%2F%2Fdumps.wikimedia.org%2Fruwiki%2F20141114%2Fruwiki-20141114-pages-meta-current.xml.bz2|/

    */
    	function ed2k_link(file){
    		var link = ["ed2k://|file"];
    		if (file && file.hash && file.name && file.size && file.hash.ed2k) {
    			link.push(encodeURIComponent(file.name));
    			link.push(file.size);
    			link.push(file.hash.ed2k);
    			if (file.hash.aich)
    				link.push("h=" + file.hash.aich);
    			
    			
    			if (file.hash_list && file.hash_list.ed2k)
    				link.push("p=" + file.hash_list.ed2k.join(":"));
    			
    			
    			if (file.url)
    				for (var i=0; i < file.url.length; i++)
    					link.push("s=" + encodeURIComponent(file.url[i]));
    				
    			
    			
    			if (file.collection)
    				for (var i=0; i < file.collection.length; i++)
    					link.push("f=" + encodeURIComponent(file.collection[i]));
    				
    			
    			
    			if (file.xurl){
    				var sources = [];
    				file.xurl.map(
    					function (xurl){
    						var matches = (/ed2kftp\:\/\/([^\/]+)\/[a-z0-9]+\/[0-9]+\//gmi).exec(xurl);
    						if (matches)
    							sources.push(matches[1]);
    					}
    				);
    				if ( sources.length > 0 )
    					link.push("/|sources," + sources.join(","));
    			}
    			
    			link.push("/");
    			return link.join("|");
    		}
    	}
    
    
    
    /*

    Полный магнит



    Этот магнит может использовать любой p2p клиент если в нём содержатся нужные ему хеши. Но справляется с этой задачей пока только Shareaza.

    Пример магнита:
    magnet:?xt=urn:ed2k:0218392e98873112284de6913efee0df&xl=2981763794&dn=ruwiki-20141114-pages-meta-current.xml.bz2&xt=urn:bitprint:U24IYRP3WTLRY5KJH7SACBLFT2LAM62U.JNOANHGPELY63I2OMSPQ3J73AS2P4AWB5MTBJCQ&xt=urn:btih:16253d9beb0df49fe30bacc62ea10ba63939f0f8&tr=http%3A%2F%2Furl2torrent.net%3A6970%2Fannounce&ws=http%3A%2F%2Fdumps.wikimedia.org%2Fruwiki%2F20141114%2Fruwiki-20141114-pages-meta-current.xml.bz2&x.do=https%3A%2F%2Fdumps.wikimedia.org%2Fruwiki%2F20141114%2F&fl=http%3A%2F%2Ftorcache.net%2Ftorrent%2F16253D9BEB0DF49FE30BACC62EA10BA63939F0F8.torrent&xs=http://cache.freebase.be/u24iyrp3wtlry5kjh7sacblft2lam62u&xs=dchub://allavtovo.ru

    */
    	function full_magnet(file, as){
    		var magnet = ["magnet:?"];
    		var amp = false;
    		if (!file) return;
    		if (file.hash){
    			if (file.hash.btih){
    				magnet.push("xt=urn:btih:");
    				magnet.push(file.hash.btih);
    				amp = true;
    			}
    			if (file.hash.sha1 && file.hash.tree_tiger){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("xt=urn:bitprint:");
    				magnet.push(file.hash.sha1);
    				magnet.push(".");
    				magnet.push(file.hash.tree_tiger);
    			}else if(file.hash.sha1){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("xt=urn:sha1:");
    				magnet.push(file.hash.sha1);
    			}else if(file.hash.tree_tiger){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("xt=urn:tree:tiger:");
    				magnet.push(file.hash.tree_tiger);
    			}
    			if (file.hash.ed2k){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("xt=urn:ed2k:");
    				magnet.push(file.hash.ed2k);
    			}
    		}
    		if (file.size) {
    			if (amp) magnet.push("&"); else amp = true;
    			magnet.push("xl=");
    			magnet.push(encodeURIComponent(file.size));
    		}
    		if (file.name) {
    			if (amp) magnet.push("&"); else amp = true;
    			magnet.push("dn=");
    			magnet.push(encodeURIComponent(file.name));
    		}
    		if (file.hash){
    			if (file.hash.aich){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("xt=urn:aich:");
    				magnet.push(file.hash.aich);
    			}
    			if (file.hash.ipfs){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("xt=urn:ipfs:");
    				magnet.push(file.hash.ipfs);
    			}
    		}
    		if (file.urns){
    			file.urns.map((urn)=>{
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("xt=");
    				magnet.push(urn);
    			})
    		}
    		if (file.trackers){
    			for (var i=0; i < file.trackers.length; i++){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("tr=");
    				magnet.push(encodeURIComponent(file.trackers[i]));
    			}
    		}
    		if (file.url){
    			for (var i=0; i < file.url.length; i++){
    				if (amp) magnet.push("&"); else amp = true;
    				if (as || !(file.hash && file.hash.btih))
    					magnet.push("as=");
    				else 
    					magnet.push("ws=");
    				magnet.push(encodeURIComponent(file.url[i]));
    			}
    		}
    		if (file.bitrate){
    			if (amp) magnet.push("&"); else amp = true;
    			magnet.push("br=");
    			magnet.push(encodeURIComponent(file.bitrate));
    		}
    		if (file.description_url){
    			for (var i=0; i < file.description_url.length; i++){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("x.do=");
    				magnet.push(encodeURIComponent(file.description_url[i]));
    			}
    		}
    		if (file.torrent_file_url){
    			for (var i=0; i < file.torrent_file_url.length; i++){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("fl=");
    				magnet.push(encodeURIComponent(file.torrent_file_url[i]));
    			}
    		}
    		if (file.collection){
    			for (var i=0; i < file.collection.length; i++){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("mt=");
    				magnet.push(encodeURIComponent(file.collection[i]));
    			}
    		}
    		if (file.hash_list && file.hash_list.ed2k){
    			if (amp) magnet.push("&"); else amp = true;
    			magnet.push("x.ed2k.p=");
    			magnet.push(file.hash_list.ed2k.join(":"));
    		}
    		if (file.xurl){
    			for (var i=0; i < file.xurl.length; i++){
    				if (amp) magnet.push("&"); else amp = true;
    				magnet.push("xs=");
    				magnet.push(file.xurl[i]);
    			}
    		}
    		if ( magnet.length > 1 )
    			return magnet.join("");
    	}
    
    
    
    /*
    Раньше в магнитах для торрента использовалось Base32 кодирование btih. Сейчас используется HEX. Shareaza по старинке использует Base32 и эта функция конвертирует btih обратно в HEX.
    */
    	function base32_to_hex(base32){
    		/* http://tools.ietf.org/html/rfc4648 */
    		if (!base32) return "";
    		var number = 0;
    		var bit_pos = 0;
    		var detector = /[2-7a-z]/gmi;
    		var hex_str = [];
    		base32.replace(detector, function(letter){
    			var val = parseInt(letter, 36);
    
    			if (val <= 7)
    				val += 24;
    			else 
    				val -= 10;
    			
    			number = ((number << 5) | val) & 255;
    			bit_pos += 5;
    			
    			for (; bit_pos >= 4;){
    				bit_pos -= 4;
    				var hex_num = (number >> bit_pos) & 15;
    				hex_str.push(hex_num.toString(16));
    			}
    		});
    		
    		return hex_str.join("");
    	}
    
    
    /*

    Бонус: Микро торрент



    Если в универсальном магните есть sha1 хеш используя его мы можем сгенерировать микро торрент файл. Это торрент в котором только одна чась которая включает весь файл. Sha1 хеш этой части совпадает в Sha1 хешем самого файла. Этот торрент можно получить из магнита что позволяет шарить в сети BitTorrent небольшие файлы без необходимости создания полноценного торрент файла. Также микро торрентом можно передать через сеть BitTorrent большой торрент файл полностью а не только info часть.
    */
    	
    	
    /* Функция подсчёта длины строки */
    	function raw_length(encodedURI){
    		var count = 0;
    		var index = 0;
    		for (index = encodedURI.indexOf("%"); index>=0 && (++count) ; index = encodedURI.indexOf("%", index+1));
    		return encodedURI.length-count*2;
    	}
    	
    /* Добавляем bencode кодированную строку */
    	function push_string(string, to_list){
    		to_list.push(raw_length(string));
    		to_list.push(":");
    		to_list.push(string);
    	}
    
    
    /*

    Функция сборки микро торрент файла.



    Для того чтобы собрать его нам нужены: sha1 хеш файла, размер файла, имя файла. Параметры в info части микро торрента записываются в алфавитном порядке по имени параметра. Это уменьшает вариативность сборки торрент файла и увеличивает вероятность получения того же btih из того же магнита. У uTorrent есть ограничение на минимальный размер части поэтому если файл меньше 16384 байт размер части устанавливается равным этому числу.

    Пример:
    data:application/x-bittorrent;,d4:infod6:lengthi10826029e4:name23:mediawiki-1.15.1.tar.gz12:piece%20lengthi10826029e6:pieces20:%bc%6f%a7%90%b7%73%88%92%c6%b4%15%fc%76%65%8a%97%67%63%71%5de8:url-listl68:http%3A%2F%2Fdownload.wikimedia.org%2Fmediawiki%2F1.15%2Fmediawiki-1.15.1.tar.gzee

    */
    	function make_micro_torrent(file){
    		if (file.name && file.size && file.hash && file.hash.sha1){
    			var torrent = ["data:application/x-bittorrent;,d"];
    			if (file.trackers && file.trackers.length>0){
    				torrent.push("8:announce");
    				push_string(file.trackers[0], torrent);
    				if (file.trackers.length>1){
    					torrent.push("13:announce-listl");
    					for (var i = 1; file.trackers.length>i; i++){
    						var tracker = encodeURIComponent(decodeURIComponent(file.trackers[i]));
    						push_string(tracker, torrent);
    					}
    					torrent.push("e");
    				}
    			}
    			torrent.push("4:infod");
    			torrent.push("6:length");
    			torrent.push("i");
    			torrent.push(file.size);
    			torrent.push("e");
    			torrent.push("4:name");
    			var name = encodeURIComponent(file.name);
    			push_string(name, torrent);
    			torrent.push("12:piece%20length");
    			torrent.push("i");
    			torrent.push(file.size < 16384 ? 16384 : file.size);
    			torrent.push("e");
    			torrent.push("6:pieces");
    			var sha1 = file.hash.sha1;
    			if (sha1.length < 40)
    				sha1 = base32_to_hex(sha1);
    			sha1 = sha1.replace(/[0-9A-Fa-f]{2}/g,"%$&");
    			push_string(sha1, torrent);
    			torrent.push("e");
    			if (file.url && file.url.length>0){
    				torrent.push("8:url-listl");
    				for (var i = 0; file.url.length>i; i++){
    					var url = encodeURIComponent(decodeURIComponent(file.url[i]));
    					push_string(url, torrent);
    				}
    				torrent.push("e");
    			}
    			torrent.push("e");
    			return torrent.join("");
    		}
    	}
    
    
    
    
    /*
    Функция для вставки новых ссылок на страницу.
    */
    
    
    	function insert_link_after(sibling, href, class_name){
    		var new_link = document.createElement("A");
    		if (href) new_link.href = href;
    		if (class_name) new_link.className = class_name;
    		return sibling.parentNode.insertBefore(new_link, sibling.nextSibling);
    	}
    
    
    
    /*

    Поехали



    Перебираем ссылки и ищем в них магниты. Ссылки перебираются в обратном порядке так как мы добавляем новые и массив ссылок автоматом увеличивается. Сейчас не проверял но раньше я на этом в бесконечный цикл попадал.
    */
    	var links = document.getElementsByTagName("A");
    	for (var i = links.length - 1; i >= 0; i--){
    		var link = links[i];
    		var magnet_index = link.href.indexOf("magnet:?");
    		var magnet_link;
    		
    		if (magnet_index < 0){
    			magnet_index = link.href.indexOf("magnet%3A%3F");
    			if( magnet_index > -1 )
    				magnet_link = try_decode(link.href.substr(magnet_index));
    		}
    		else 
    			magnet_link = link.href.substr(magnet_index);
    		
    		if (magnet_index > -1){
    			var file = parse_magnet(magnet_link);
    			if ( file.name ){
    				var spliter = "/" + file.name + "#magnet";
    				if ( link.href.indexOf( spliter ) > -1 ){
    					/*
    					URL + magnet
    					Добавляем прямую ссылку на файл.
    					*/
    					
    					if (!file.url) file.url = [];
    					file.url.push(link.href.split( spliter )[0] + "/" + file.name);
    				}
    			}
    			
    			var link_functions = {
    				"micro-torrent": make_micro_torrent, 
    				"torrent-magnet":torrent_magnet, 
    				"dc-magnet": dc_magnet, 
    				"ed2k-link": ed2k_link, 
    				"full-magnet": full_magnet};
    			
    			for (var name in link_functions){
    				var href = link_functions[name](file);
    				if (href){
    					var a = insert_link_after(link, href, name);
    					if ( name == "micro-torrent" ){
    						/* Используем атрибут download для того чтоб задать имя торрент файла. */
    						a.setAttribute("download", (file.name) + ".micro.torrent");
    					}
    						
    				}
    					
    			}
    		}
    	}
    	
    
    /*
    Текст ссылкам зададим через стили. Так же можно и картинки вписать в виде Data URI.
    */
    
    	document.head.appendChild(document.createElement('style')).appendChild(document.createTextNode(`
    		[class*='-magnet'], .ed2k-link, .micro-torrent{
    			margin-left: 1em
    		}
    		a[class*='-magnet']:before, .ed2k-link:before, .micro-torrent:before{
    			content: attr(class)
    		}`))
    })();
    void(0);
    

    Установка



    1. Копируем папку «magnet-converter» с содержимым на локальный диск.
    2. В браузере Chrome открываем «chrome://extensions/» или «Главное Меню > Дополнительные инструменты > Расширения»
    3. Ставим галочку «Режим разработчика»
    4. Нажимаем «Загрузить распакованное расширение...»
    5. Находим и выбираем папку «magnet-converter» со скриптами.
    6. Нажимаем ОК.

    Тест



    Ссылка для теста скрипта:

    imageТест

    Результат должен выглядеть так:

    imageТест full-magnet ed2k-link dc-magnet torrent-magnet micro-torrent
    Появятся 5 дополнительных ссылок для разных p2p клиентов.

    Заключение


    Надеюсь что разработчики p2p клиентов допишут код так что бы универсальный магнит распознавался клиентом корректно и отпадёт необходимость его делить.

    Ссылки:


    Интернет на магнитах 1 — Магнит
    Интернет на магнитах 2 — Гипертекст
    Интернет на магнитах 3 — P2P Сайт и Форум
    Интернет на магнитах 4 — Делим магнит на части
    Интернет на магнитах 5 — Маяки и сообщения(личные, публичные и обновления)
    Поделиться публикацией

    Комментарии 12

      +1
      Хм, а если такой вариант:
      Ресурс, каталогизирующий фильмы и их описания.
      К каждому фильму — краткое описание, постер и отзыв автора: «после просмотра фильма меня посетило вдохновение и у меня родился стих:»
      Далее идёт «белый» стих, который с помощью нехитрого скрипта преобразуется в magnet-ссылку.

      Как его(сайт) можно будет «закрыть»?
        0

        В статье "Децентрализация контента сайта" я предлагал похожую схему:
        На странице находится такое содержимое.


        <audio>
            Vivaldi Summer mvt 1 Allegro non molto - John Harrison violin
        </audio>

        Сервис(пользовательский скрипт) подключенный пользователем читает это содержимое и меняет на конкретные источники.


        <audio>
            < source src="http://upload.wikimedia.org/wikipedia/commons/1/19/04_-_Vivaldi_Summer_mvt_1_Allegro_non_molto_-_John_Harrison_violin.ogg">
        </audio>

        Может также и магнит подставлять.

          0
          а смысл использовать стеганографию если намного проще использовать любой P2P веб для избежания блокировок?
            0

            У меня возникала немного другая идея:
            Есть два сайта. Чтобы получить ссылку целиком надо заглянуть на оба (например, сделать xor от данных с одного сайта и с другого). Получится, что самой ссылки в явном виде нигде нет.

              0
              Делов-то — блокирнут оба.
            0
            Всё не так просто даже с психологической стороны. Юзер должен знать, что он раздаёт загруженный контент. Так же он должен знать, что в некоторых случаях желательно пробросить порт. Ну и так далее.

            Касаемо магнитов в вебе — это утопия. В смысле смотреть контент на страницах скаченных из p2p. Там есть куча НО. Как дополнение ещё можно рассматривать, но полная замена — это не реально.
            Вот приемлемая реализация для p2p веба http://rutracker.org/forum/viewtopic.php?t=5273682
            То есть:
            1. Поднимается свой прокси сервер, настройки которого пользователь меняет в своём utorrent
            2. Сервер автоматом определяет за NAT или белым IP юзер. Если за NAT — делает ссылку через прокси. Если белый IP делает прямую ссылку на компьютер.
            3. Сервер должен быть связан с трекером, что бы брать с них IP тех юзеров кто находится на раздаче. И потом обратившись к этим IP получить с них http ссылки, которые подставятся на сайт.

            Сложно это всё.

              0
              В смысле смотреть контент на страницах скаченных из p2p. Там есть куча НО.

              Разъясните по подробней пожалуйста.


              Я не предлагаю полную замену вебу. Магниты его дополняют. Дают альтернативные пути получения контента а также его проверки.


              Интернет на магнитах не зависим от протоколов и способов доставки. Так что можно использовать и ваш способ для его реализации.


              У Shareaza нет прокси сервера. Но если клиент не за NAT расшарить файл на обычный веб в ней тоже можно удалив фильтр User-Agent "Mozilla" в настройках раздач. И скопировать веб ссылку на файл поставив галку "Включить меня как фиксированный источник"
              Пример:
              http://198.51.100.0:6346/uri-res/N2R?urn:sha1:NNP6HWVUQBBDYJKZCGNUEBPPSBZOEADY


              Можно к ней также добавить магнит:
              http://198.51.100.0:6346/uri-res/N2R?urn:sha1:NNP6HWVUQBBDYJKZCGNUEBPPSBZOEADY#magnet:?xt=urn:bitprint:NNP6HWVUQBBDYJKZCGNUEBPPSBZOEADY.GC3J2KPOBLMFC4JJDDTRJ22HUI7MZKVYNG5QDMI&xt=urn:ed2khash:e2396e000b26782e68a304a5edbc2423&xt=urn:btih:JZG37YB344CTNOWGPZEJZH6ZPQ5WDRHZ&xl=15517842&dn=Shareaza_2.7.9.1_Win32_Debug_2016-09-02.exe&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&xs=http%3A%2F%2F198.51.100.0%3A6346%2Furi-res%2FN2R%3Furn%3Asha1%3ANNP6HWVUQBBDYJKZCGNUEBPPSBZOEADY


              Таким образом если файл перестаёт быть доступен с моего сервера в ссылке достаточно информации чтобы найти файл и в обычном интернете и в доступных p2p сетях. Главное чтоб он там был.

                0
                Браузер должен сразу открывать объект по ссылке, а не ждать пока найдутся и соберутся пиры. В добавок, браузер должен уметь работать со всеми p2p сетями, что бы обходиться без сторонних p2p программ. То есть альтернативы для http ссылки нет.
                  0

                  HTTP это лиш протокол передачи данных. Запустите на сервере aMule и контент будет немедленно и круглосуточно доступен в Edonkey2000. Поставьте на сервер Transmission и контент будет доступен по протоколу Bittorrent. Тоже самое думаю возможно сделать и для сети Direct Connect. А для Gnutella2 подойдёт и обычный веб-сервер.


                  Согласен с тем что переход по ссылкам должен быть таким же мгновенным как и веб-серфинг.


                  Работа браузера со всеми p2p протоколами это лишнее. Что бы я добавил в браузер так это проверку хешей, подписей и умение загружать файл из многих источников и проверку по частям. Ну ещё отдавать файл обратно из кеша тоже было бы не плохо. А переводом с HTTP на другие протоколы может занятся локальный прокси который может быть по совместительству любым p2p клиентом.


                  Кстати у браузеров тоже появился свой p2p протокол — WebRTC. На основе его сделали webtorrent.

              0
              ivan386 Что вы думаете о проекте ipfs?
                0

                IPFS ещё одна p2p сеть. Это не плохо. Почему то не используют магниты либо Content-Addressable Web. Судя по комментарию сейчас ипользуется для адресации sha256 но обёрнутый в мультихеш и используют свой формат ссылок. Похвально что не забыли о тех у кого не стоит клиент и им доступен контент через прокси сайт https://ipfs.io/ (пример).


                Для того что бы составить более объективное мнение нужно её поставить, потестировать, порыться в коде. Не совсем понял как считается хеш поскольку если взять sha256 хеш файла по ссылке https://ipfs.io/ipfs/QmcXx5mKDQAc7tCWLq84Hn7XFxWfBdZpvogJk3tNXQRFiv то он не совпадает с тем что в ссылке.

                0

                Теперь скрипт можно использовать и из закладок.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое