implement InfoHash torrent data type
This commit is contained in:
parent
b7b772af86
commit
670b11b49a
5 changed files with 146 additions and 1 deletions
|
|
@ -17,5 +17,8 @@ When there is need to expose local tracker a tracker endpoint should be declare
|
||||||
is HTTP or UDP server responsing to BitTorrent announces just like if it was any other regular torrent tracker.
|
is HTTP or UDP server responsing to BitTorrent announces just like if it was any other regular torrent tracker.
|
||||||
|
|
||||||
|
|
||||||
|
Announce request coming from local peer contains local (peer) data: ID, uploaded, downloaded, and so on.
|
||||||
|
Announce response contains peer set.
|
||||||
|
|
||||||
Maven exec with args:
|
Maven exec with args:
|
||||||
mvn exec:java -Dexec.args=''
|
mvn exec:java -Dexec.args=''
|
||||||
5
pom.xml
5
pom.xml
|
|
@ -70,6 +70,11 @@
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>2.18.0</version>
|
<version>2.18.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>1.17.1</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ public class App {
|
||||||
private static final Logger log = LoggerFactory.getLogger(App.class);
|
private static final Logger log = LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
final Option logDirOpt = new Option("l", "log", true, "log dir path");
|
|
||||||
final Option configFileOpt = new Option("c", "config", true, "config.json path");
|
final Option configFileOpt = new Option("c", "config", true, "config.json path");
|
||||||
|
final Option logDirOpt = new Option("l", "log", true, "log dir path");
|
||||||
final Options options = new Options()
|
final Options options = new Options()
|
||||||
.addOption(configFileOpt)
|
.addOption(configFileOpt)
|
||||||
.addOption(logDirOpt);
|
.addOption(logDirOpt);
|
||||||
|
|
|
||||||
70
src/main/java/com/mykola2312/retracker/tracker/InfoHash.java
Normal file
70
src/main/java/com/mykola2312/retracker/tracker/InfoHash.java
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.mykola2312.retracker.tracker;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.DecoderException;
|
||||||
|
import org.apache.commons.codec.net.URLCodec;
|
||||||
|
|
||||||
|
public class InfoHash {
|
||||||
|
public static final int HASH_LENGTH = 20;
|
||||||
|
|
||||||
|
private byte[] hash = null;
|
||||||
|
|
||||||
|
public InfoHash() {
|
||||||
|
this.hash = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InfoHash(byte[] hash) {
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] bytes() {
|
||||||
|
return this.hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fromURLEncoded(String urlParam) throws DecoderException {
|
||||||
|
this.hash = URLCodec.decodeUrl(urlParam.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toURLEncoded() {
|
||||||
|
return new String(URLCodec.encodeUrl(new BitSet(), this.hash), StandardCharsets.US_ASCII);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fromString(String hashString) throws Exception {
|
||||||
|
if (hashString.length() != InfoHash.HASH_LENGTH * 2) {
|
||||||
|
throw new Exception(String.format("hash is not 40 characters length: %s, %d", hashString, hashString.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] bytePair = new char[2];
|
||||||
|
hash = new byte[InfoHash.HASH_LENGTH];
|
||||||
|
for (int i = 0; i < InfoHash.HASH_LENGTH; i++) {
|
||||||
|
hashString.getChars(i*2, i*2 + 2, bytePair, 0);
|
||||||
|
hash[i] = (byte)Short.parseShort(new String(bytePair), 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder out = new StringBuilder();
|
||||||
|
for (int i = 0; i < InfoHash.HASH_LENGTH; i++) {
|
||||||
|
out.append(String.format("%02x", hash[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == this) return true;
|
||||||
|
if (!(o instanceof InfoHash)) return false;
|
||||||
|
InfoHash other = (InfoHash)o;
|
||||||
|
return Arrays.equals(this.hash, other.hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int hashCode() {
|
||||||
|
return this.hash != null ? Arrays.hashCode(this.hash) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.mykola2312.retracker.tracker;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class InfoHashTest {
|
||||||
|
@Test
|
||||||
|
public void testHashString() {
|
||||||
|
final String hashString = "360775c6629eb06e60d90201aed1b7bc49a1ce16";
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
InfoHash hash = new InfoHash();
|
||||||
|
|
||||||
|
hash.fromString(hashString);
|
||||||
|
assertEquals(hashString, hash.toString());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHashEquals() {
|
||||||
|
final String hashString = "360775c6629eb06e60d90201aed1b7bc49a1ce16";
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
InfoHash hashOne = new InfoHash();
|
||||||
|
InfoHash hashTwo = new InfoHash();
|
||||||
|
|
||||||
|
hashOne.fromString(hashString);
|
||||||
|
hashTwo.fromString(hashString);
|
||||||
|
|
||||||
|
assertEquals(true, hashOne.equals(hashTwo));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHashCode() {
|
||||||
|
final String hashString = "360775c6629eb06e60d90201aed1b7bc49a1ce16";
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
InfoHash hashOne = new InfoHash();
|
||||||
|
InfoHash hashTwo = new InfoHash();
|
||||||
|
|
||||||
|
hashOne.fromString(hashString);
|
||||||
|
hashTwo.fromString(hashString);
|
||||||
|
|
||||||
|
assertEquals(true, hashOne.hashCode() == hashTwo.hashCode());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testURLEncode() {
|
||||||
|
final String hashString = "360775c6629eb06e60d90201aed1b7bc49a1ce16";
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
InfoHash first = new InfoHash();
|
||||||
|
first.fromString(hashString);
|
||||||
|
|
||||||
|
InfoHash second = new InfoHash();
|
||||||
|
second.fromURLEncoded(first.toURLEncoded());
|
||||||
|
|
||||||
|
System.out.printf("url encoded hash: %s\n", first.toURLEncoded());
|
||||||
|
|
||||||
|
assertEquals(first, second);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue