Skip to content

Commit f1a6504

Browse files
committed
initial commit
0 parents  commit f1a6504

File tree

12 files changed

+331
-0
lines changed

12 files changed

+331
-0
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
*.class
2+
3+
build/**
4+
dist/**
5+
.idea/**
6+
7+
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
8+
hs_err_pid*

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2015 Ian Preston
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# java-multihash
2+
A Java implementation of Multibase
3+
4+
## Usage
5+
Multihash m = Multihash.fromBase58("QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy");
6+
7+
## Compilation
8+
To compile just run ant.

build.xml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<project name="java-multibase" default="dist" basedir=".">
2+
<description>
3+
Java Multibase
4+
</description>
5+
6+
<property name="src" location="src"/>
7+
<property name="build" location="build"/>
8+
<property name="dist" location="dist"/>
9+
10+
<path id="dep.runtime">
11+
<fileset dir="./lib">
12+
<include name="**/*.jar" />
13+
</fileset>
14+
</path>
15+
16+
<target name="init">
17+
<mkdir dir="${build}"/>
18+
</target>
19+
20+
<target name="compile" depends="init" description="compile the source">
21+
<javac includeantruntime="false" srcdir="${src}" destdir="${build}" debug="true" debuglevel="lines,vars,source">
22+
<classpath>
23+
<fileset dir="lib">
24+
<include name="**/*.jar" />
25+
</fileset>
26+
</classpath>
27+
</javac>
28+
</target>
29+
30+
<target name="dist" depends="compile" description="generate the distribution">
31+
<mkdir dir="${dist}/lib"/>
32+
<copy todir="${dist}/lib">
33+
<fileset dir="lib"/>
34+
</copy>
35+
<manifestclasspath property="manifest_cp" jarfile="myjar.jar">
36+
<classpath refid="dep.runtime" />
37+
</manifestclasspath>
38+
<jar jarfile="${dist}/multibase.jar" basedir="${build}">
39+
<manifest>
40+
<attribute name="Class-Path" value="${manifest_cp}"/>
41+
</manifest>
42+
</jar>
43+
<copy todir=".">
44+
<fileset file="${dist}/multibase.jar"/>
45+
</copy>
46+
</target>
47+
48+
49+
<target name="test" depends="compile,dist">
50+
<junit printsummary="yes" fork="true" haltonfailure="yes">
51+
<jvmarg value="-Xmx1g"/>
52+
<classpath>
53+
<pathelement location="lib/junit-4.11.jar" />
54+
<pathelement location="lib/hamcrest-core-1.3.jar" />
55+
<pathelement location="multibase.jar" />
56+
</classpath>
57+
<test name="io.ipfs.api.MultibaseTests" haltonfailure="yes">
58+
<formatter type="plain"/>
59+
<formatter type="xml"/>
60+
</test>
61+
</junit>
62+
</target>
63+
64+
<target name="clean" description="clean up">
65+
<delete dir="${build}"/>
66+
<delete dir="${dist}"/>
67+
</target>
68+
</project>

lib/hamcrest-core-1.3.jar

44 KB
Binary file not shown.

lib/junit-4.12.jar

308 KB
Binary file not shown.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.ipfs.multibase;
2+
3+
public class Base16 {
4+
public static byte[] decode(String hex)
5+
{
6+
byte[] res = new byte[hex.length()/2];
7+
for (int i=0; i < res.length; i++)
8+
res[i] = (byte) Integer.parseInt(hex.substring(2*i, 2*i+2), 16);
9+
return res;
10+
}
11+
12+
public static String encode(byte[] data)
13+
{
14+
StringBuilder s = new StringBuilder();
15+
for (byte b : data)
16+
s.append(String.format("%02x", b & 0xFF));
17+
return s.toString();
18+
}
19+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package io.ipfs.multibase;
2+
3+
/**
4+
* Copyright 2011 Google Inc.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import java.math.BigInteger;
20+
21+
/**
22+
* A custom form of base58 is used to encode BitCoin addresses. Note that this is not the same base58 as used by
23+
* Flickr, which you may see reference to around the internet.<p>
24+
*
25+
* Satoshi says: why base-58 instead of standard base-64 encoding?<p>
26+
*
27+
* <ul>
28+
* <li>Don't want 0OIl characters that look the same in some fonts and
29+
* could be used to create visually identical looking account numbers.</li>
30+
* <li>A string with non-alphanumeric characters is not as easily accepted as an account number.</li>
31+
* <li>E-mail usually won't line-break if there's no punctuation to break at.</li>
32+
* <li>Doubleclicking selects the whole number as one word if it's all alphanumeric.</li>
33+
* </ul>
34+
*/
35+
public class Base58 {
36+
private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
37+
private static final BigInteger BASE = BigInteger.valueOf(58);
38+
39+
public static String encode(byte[] input) {
40+
// TODO: This could be a lot more efficient.
41+
BigInteger bi = new BigInteger(1, input);
42+
StringBuffer s = new StringBuffer();
43+
while (bi.compareTo(BASE) >= 0) {
44+
BigInteger mod = bi.mod(BASE);
45+
s.insert(0, ALPHABET.charAt(mod.intValue()));
46+
bi = bi.subtract(mod).divide(BASE);
47+
}
48+
s.insert(0, ALPHABET.charAt(bi.intValue()));
49+
// Convert leading zeros too.
50+
for (byte anInput : input) {
51+
if (anInput == 0)
52+
s.insert(0, ALPHABET.charAt(0));
53+
else
54+
break;
55+
}
56+
return s.toString();
57+
}
58+
59+
public static byte[] decode(String input) {
60+
byte[] bytes = decodeToBigInteger(input).toByteArray();
61+
// We may have got one more byte than we wanted, if the high bit of the next-to-last byte was not zero. This
62+
// is because BigIntegers are represented with twos-compliment notation, thus if the high bit of the last
63+
// byte happens to be 1 another 8 zero bits will be added to ensure the number parses as positive. Detect
64+
// that case here and chop it off.
65+
boolean stripSignByte = bytes.length > 1 && bytes[0] == 0 && bytes[1] < 0;
66+
// Count the leading zeros, if any.
67+
int leadingZeros = 0;
68+
for (int i = 0; input.charAt(i) == ALPHABET.charAt(0); i++) {
69+
leadingZeros++;
70+
}
71+
// Now cut/pad correctly. Java 6 has a convenience for this, but Android can't use it.
72+
byte[] tmp = new byte[bytes.length - (stripSignByte ? 1 : 0) + leadingZeros];
73+
System.arraycopy(bytes, stripSignByte ? 1 : 0, tmp, leadingZeros, tmp.length - leadingZeros);
74+
return tmp;
75+
}
76+
77+
public static BigInteger decodeToBigInteger(String input) {
78+
BigInteger bi = BigInteger.valueOf(0);
79+
// Work backwards through the string.
80+
for (int i = input.length() - 1; i >= 0; i--) {
81+
int alphaIndex = ALPHABET.indexOf(input.charAt(i));
82+
if (alphaIndex == -1) {
83+
throw new IllegalStateException("Illegal character " + input.charAt(i) + " at " + i);
84+
}
85+
bi = bi.add(BigInteger.valueOf(alphaIndex).multiply(BASE.pow(input.length() - 1 - i)));
86+
}
87+
return bi;
88+
}
89+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package io.ipfs.multibase;
2+
3+
import java.util.*;
4+
5+
public class Multibase {
6+
7+
public enum Base {
8+
Base1('1'),
9+
Base2('0'),
10+
Base8('7'),
11+
Base10('9'),
12+
Base16('f'),
13+
Base58Flickr('Z'),
14+
Base58BTC('z');
15+
16+
public char prefix;
17+
18+
Base(char prefix) {
19+
this.prefix = prefix;
20+
}
21+
22+
private static Map<Character, Base> lookup = new TreeMap<>();
23+
static {
24+
for (Base b: Base.values())
25+
lookup.put(b.prefix, b);
26+
}
27+
28+
public static Base lookup(char p) {
29+
if (!lookup.containsKey(p))
30+
throw new IllegalStateException("Unknown Multibase type: " + p);
31+
return lookup.get(p);
32+
}
33+
}
34+
35+
public static String encode(Base b, byte[] data) {
36+
switch (b) {
37+
case Base58BTC:
38+
return b.prefix + Base58.encode(data);
39+
case Base16:
40+
return b.prefix + Base16.encode(data);
41+
default:
42+
throw new IllegalStateException("Unsupported base encoding: " + b.name());
43+
}
44+
}
45+
46+
public static Base encoding(String data) {
47+
return Base.lookup(data.charAt(0));
48+
}
49+
50+
public static byte[] decode(String data) {
51+
Base b = encoding(data);
52+
String rest = data.substring(1);
53+
switch (b) {
54+
case Base58BTC:
55+
return Base58.decode(rest);
56+
case Base16:
57+
return Base16.decode(rest);
58+
default:
59+
throw new IllegalStateException("Unsupported base encoding: " + b.name());
60+
}
61+
}
62+
}

src/main/main.iml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<module type="JAVA_MODULE" version="4">
3+
<component name="NewModuleRootManager" inherit-compiler-output="true">
4+
<exclude-output />
5+
<content url="file://$MODULE_DIR$">
6+
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
7+
</content>
8+
<orderEntry type="inheritedJdk" />
9+
<orderEntry type="sourceFolder" forTests="false" />
10+
</component>
11+
</module>

0 commit comments

Comments
 (0)