Skip to content

Commit

Permalink
Merge pull request #100 from trendmicro/bugfix_issue_99
Browse files Browse the repository at this point in the history
Java fix for issue #99
  • Loading branch information
jonjoliver authored Apr 23, 2021
2 parents 9e7d50c + 0034af2 commit d65f93b
Show file tree
Hide file tree
Showing 14 changed files with 808 additions and 468 deletions.
24 changes: 20 additions & 4 deletions java/.classpath
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/test/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/java">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
4 changes: 2 additions & 2 deletions java/.project
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>tlsh</name>
<comment>Project tlsh created by Buildship.</comment>
<comment></comment>
<projects>
</projects>
<buildSpec>
Expand All @@ -17,7 +17,7 @@
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
1 change: 0 additions & 1 deletion java/.settings/org.eclipse.buildship.core.prefs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
13 changes: 11 additions & 2 deletions java/.settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
#
#Tue Apr 20 07:46:11 EDT 2021
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
42 changes: 7 additions & 35 deletions java/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,16 @@ This port has no additional JAR dependencies and only requires the JRE.

## Use with gradle

Pre-built versions of TLSH are hosted on bintray and can be used in gradle build scripts as follows:
Pre-built TLSH libraries will be available on Maven Central soon but for now they
must be built from source.

```
repositories {
jcenter()
// ... other repositories
}
dependencies {
compile 'com.trendmicro:tlsh:3.7.1'
// ... other dependencies
}
```bash
git clone https://github.com/trendmicro/tlsh.git
cd tlsh/java
./gradlew clean build
```

## Use with Maven

Pre-built versions of TLSH can be used in a Maven pom.xml file as follows:

```xml
<repositories>
<repository>
<id>jcenter</id>
<url>https://jcenter.bintray.com/</url>
</repository>
<!-- ... other repositories -->
</repositories>

<dependencies>
<dependency>
<groupId>com.trendmicro</groupId>
<artifactId>tlsh</artifactId>
<version>3.7.1</version>
<type>pom</type>
</dependency>
<!-- ... other dependencies -->
</dependencies>
```
This will produce JAR files in `build/libs` that can be included in other projects.

## Example
```java
Expand Down
52 changes: 6 additions & 46 deletions java/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,16 @@
* user guide available at https://docs.gradle.org/3.5/userguide/java_library_plugin.html
*/

// Apply the required plugins
plugins {
id "com.jfrog.bintray" version "1.7.3"
id 'java'
id 'java-library'
id 'eclipse'
}

// Apply the required plugins
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: 'java'
apply plugin: 'java-library'

// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}

dependencies {
Expand All @@ -29,7 +24,7 @@ dependencies {
}

sourceCompatibility = 1.7
version = '3.7.1'
version = '4.5.0'
def globalVersion = version
group = 'com.trendmicro'

Expand All @@ -40,41 +35,6 @@ jar {
}
}

// To upload to bintray, run
// ./gradlew bintrayUpload
bintray {
user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER')
key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')

pkg {
repo = 'tlsh'
name = 'TLSH'

version {
name = globalVersion
desc = 'TLSH - Trend Micro Locality Sensitive Hash'
released = new Date()
}

}

publications = ['tlsh']
}

// Create the publication with the pom configuration:
publishing {
publications {
tlsh(MavenPublication) {
from components.java
artifact javadocJar
artifact sourcesJar
groupId 'com.trendmicro'
artifactId 'tlsh'
version globalVersion
}
}
}

task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
Expand Down
2 changes: 1 addition & 1 deletion java/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
7 changes: 0 additions & 7 deletions java/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,4 @@
* in the user guide at https://docs.gradle.org/3.5/userguide/multi_project_builds.html
*/

/*
// To declare projects as part of a multi-project build use the 'include' method
include 'shared'
include 'api'
include 'services:webservice'
*/

rootProject.name = 'tlsh'
36 changes: 26 additions & 10 deletions java/src/main/java/com/trendmicro/tlsh/Tlsh.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,26 @@ public class Tlsh {
* If the given string cannot be parsed correctly
*/
public static Tlsh fromTlshStr(String tlshStr) throws IllegalArgumentException {
VersionOption versionOption = null;
int[] checksum = null;
int[] tmp_code = null;
for (BucketOption bucketOption : BucketOption.values()) {
for (ChecksumOption checksumOption : ChecksumOption.values()) {
if (tlshStr.length() == hashStringLength(bucketOption, checksumOption)) {
checksum = new int[checksumOption.getChecksumLength()];
tmp_code = new int[bucketOption.getBucketCount() / 4];
}
for (VersionOption tryVersion : VersionOption.values()) {
if (tlshStr.length() == hashStringLength(bucketOption, checksumOption, tryVersion)) {
checksum = new int[checksumOption.getChecksumLength()];
tmp_code = new int[bucketOption.getBucketCount() / 4];
versionOption = tryVersion;
break;
}
}
}
}
if (checksum == null) {
throw new IllegalArgumentException("Invalid hash string, length does not match any known encoding");
}

int offset = 0;
int offset = versionOption.getVersionString().length();
for (int k = 0; k < checksum.length; k++) {
checksum[k] = TlshUtil.from_hex_swapped(tlshStr, offset);
offset += 2;
Expand All @@ -119,34 +124,44 @@ public static Tlsh fromTlshStr(String tlshStr) throws IllegalArgumentException {
offset += 2;
}

return new Tlsh(checksum, Lvalue, qRatios >> 4, qRatios & 0xF, tmp_code);
return new Tlsh(versionOption, checksum, Lvalue, qRatios >> 4, qRatios & 0xF, tmp_code);
}

/**
* Get the length of the encoded output string for different
* hash creation options
*/
private static int hashStringLength(BucketOption bucketOption, ChecksumOption checksumOption) {
return (bucketOption.getBucketCount() / 2) + (checksumOption.getChecksumLength() * 2) + 4;
private static int hashStringLength(BucketOption bucketOption, ChecksumOption checksumOption, VersionOption versionOption) {
return versionOption.getVersionString().length() + (bucketOption.getBucketCount() / 2) + (checksumOption.getChecksumLength() * 2) + 4;
}

/////////////////////////////////////////////////////////////
// Instance stuff
//
private final VersionOption version;
private final int[] checksum; // 1 or 3 bytes
private final int Lvalue; // 1 byte
private final int Q1ratio; // 4 bits
private final int Q2ratio; // 4 bits
private final int[] codes; // 32/64 bytes

Tlsh(int[] checksum, int lvalue, int q1ratio, int q2ratio, int[] codes) {
Tlsh(VersionOption versionOption, int[] checksum, int lvalue, int q1ratio, int q2ratio, int[] codes) {
this.version = versionOption;
this.checksum = checksum;
Lvalue = lvalue;
Q1ratio = q1ratio;
Q2ratio = q2ratio;
this.codes = codes;
}

/**
* Return the version this hash was created with
* @return the version this hash was created with
*/
public VersionOption getVersion() {
return version;
}

/**
* Convert this object to a string; equivalent to {@link #getEncoded()}
*
Expand All @@ -166,6 +181,7 @@ public String getEncoded() {
// The C++ code reverses the order of some of the fields before
// converting to hex, so copy that behaviour.
StringBuilder sb = new StringBuilder(hashStringLength());
sb.append(version.getVersionString());

for (int k = 0; k < checksum.length; k++) {
TlshUtil.to_hex_swapped(checksum[k], sb);
Expand All @@ -185,7 +201,7 @@ public String getEncoded() {
*/
private int hashStringLength() {
// extra 4 characters come from length and Q1 and Q2 ratio.
return codes.length * 2 + checksum.length * 2 + 4;
return version.getVersionString().length() + codes.length * 2 + checksum.length * 2 + 4;
}

/**
Expand Down
Loading

0 comments on commit d65f93b

Please sign in to comment.