Skip to content
This repository was archived by the owner on Aug 23, 2020. It is now read-only.

Commit 59dc84e

Browse files
alon-ejakubcech
authored andcommitted
document converter (#1130)
* document public used converters. re-org methods based on usage pattern. * fix documentation
1 parent b5c60d2 commit 59dc84e

File tree

1 file changed

+175
-84
lines changed

1 file changed

+175
-84
lines changed

src/main/java/com/iota/iri/utils/Converter.java

Lines changed: 175 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22

33
import java.util.Arrays;
44

5+
/**
6+
* Converts between different representations of trytes, bytes, trits and numbers.
7+
*
8+
* <p>
9+
* The IOTA protocol is represented in Trits and Trytes, while data is stored and broadcast in Bytes.
10+
* This class is used to convert between the representations.
11+
* </p>
12+
* <p>
13+
* This class also provides additional conversion tools:
14+
* <ul>
15+
* <li>Converting Trits to numerical values based on <i>Balanced ternary</i> arithmetic</li>
16+
* <li>Converting ascii to a Tryte string</li>
17+
* </ul>
18+
* </p>
19+
*/
520
public class Converter {
621

722
public static final int RADIX = 3;
@@ -21,7 +36,7 @@ public class Converter {
2136

2237
public static final int MIN_TRYTE_VALUE = -13, MAX_TRYTE_VALUE = 13;
2338

24-
39+
//lookup tables for bytes->trits and trytes->trits conversion
2540
static {
2641

2742
final byte[] trits = new byte[NUMBER_OF_TRITS_IN_A_BYTE];
@@ -35,26 +50,41 @@ public class Converter {
3550
TRYTE_TO_TRITS_MAPPINGS[i] = Arrays.copyOf(trits, NUMBER_OF_TRITS_IN_A_TRYTE);
3651
increment(trits, NUMBER_OF_TRITS_IN_A_TRYTE);
3752
}
38-
}
39-
40-
public static long longValue(final byte[] trits, final int srcPos, final int size) {
4153

42-
long value = 0;
43-
for (int i = size; i-- > 0; ) {
44-
value = value * RADIX + trits[srcPos + i];
54+
}
55+
private static void increment(final byte[] trits, final int size) {
56+
for (int i = 0; i < size; i++) {
57+
if (++trits[i] > Converter.MAX_TRIT_VALUE) {
58+
trits[i] = Converter.MIN_TRIT_VALUE;
59+
} else {
60+
break;
61+
}
4562
}
46-
return value;
4763
}
4864

65+
// Bytes <-> Trits
66+
67+
/**
68+
* Allocates a byte array large enough to fit trits, used for converting trits to bytes.
69+
*
70+
* @param tritCount length of trit array (to be converted)
71+
* @return a new byte array large enough to fit trits
72+
*/
4973
public static byte[] allocateBytesForTrits(int tritCount) {
5074
final int expectedLength = (tritCount + NUMBER_OF_TRITS_IN_A_BYTE - 1) / NUMBER_OF_TRITS_IN_A_BYTE;
5175
return new byte[expectedLength];
5276
}
5377

54-
public static byte[] allocateTritsForTrytes(int tryteCount) {
55-
return new byte[tryteCount * NUMBER_OF_TRITS_IN_A_TRYTE];
56-
}
57-
78+
/**
79+
* Converts trits array to bytes array based on {@link #NUMBER_OF_TRITS_IN_A_BYTE}.<br>
80+
* this method will override the content of {@code dest}
81+
*
82+
* @param trits source trits array
83+
* @param srcPos starting position for trits
84+
* @param dest destination bytes array
85+
* @param destPos starting position for destination bytes array
86+
* @param tritsLength amount of trits to convert
87+
*/
5888
public static void bytes(final byte[] trits, final int srcPos, byte[] dest, int destPos, final int tritsLength) {
5989

6090
final int expectedLength = (tritsLength + NUMBER_OF_TRITS_IN_A_BYTE - 1) / NUMBER_OF_TRITS_IN_A_BYTE;
@@ -72,10 +102,36 @@ public static void bytes(final byte[] trits, final int srcPos, byte[] dest, int
72102
}
73103
}
74104

105+
/**
106+
* Converts trits array to bytes array. <br>
107+
* this method will override the content of {@code dest}
108+
* @see #bytes(byte[], int, byte[], int, int)
109+
*
110+
* @param trits source trits array
111+
* @param dest destination bytes array
112+
*/
75113
public static void bytes(final byte[] trits, byte[] dest) {
76114
bytes(trits, 0, dest, 0, trits.length);
77115
}
78116

117+
/**
118+
* Allocates trits (a byte array) large enough to fit trytes, used for converting trytes to trits.
119+
*
120+
* @param tryteCount length of tryte array (to be converted)
121+
* @return a new byte array large enough to fit trytes
122+
*/
123+
public static byte[] allocateTritsForTrytes(int tryteCount) {
124+
return new byte[tryteCount * NUMBER_OF_TRITS_IN_A_TRYTE];
125+
}
126+
127+
/**
128+
* Converts bytes array to trits array based on {@link #NUMBER_OF_TRITS_IN_A_BYTE}.<br>
129+
* the inverse of {@link #bytes(byte[], int, byte[], int, int)}. <br>
130+
* this method will override the content of {@code trits}
131+
*
132+
* @param bytes source bytes array
133+
* @param trits destination trits array
134+
*/
79135
public static void getTrits(final byte[] bytes, final byte[] trits) {
80136

81137
int offset = 0;
@@ -88,6 +144,17 @@ public static void getTrits(final byte[] bytes, final byte[] trits) {
88144
}
89145
}
90146

147+
148+
149+
// Trytes <-> Trits
150+
/**
151+
* Converts a tryte string to trits (bytes array) based on {@link #NUMBER_OF_TRITS_IN_A_TRYTE}.<br>
152+
* this method will override the content of {@code dest}
153+
*
154+
* @param trytes source trytes string
155+
* @param dest destination trits array
156+
* @param destOffset starting position for destination bytes array
157+
*/
91158
public static void trits(final String trytes, byte[] dest, int destOffset) {
92159
if((dest.length - destOffset) < trytes.length() * NUMBER_OF_TRITS_IN_A_TRYTE) {
93160
throw new IllegalArgumentException("Destination array is not large enough.");
@@ -99,8 +166,81 @@ public static void trits(final String trytes, byte[] dest, int destOffset) {
99166
}
100167
}
101168

102-
public static void copyTrits(final long value, final byte[] destination, final int offset, final int size) {
169+
/**
170+
* Converts trits (bytes array)to a tryte string based on {@link #NUMBER_OF_TRITS_IN_A_TRYTE}.<br>
171+
* the inverse of {@link #trits(String, byte[], int)}.
172+
*
173+
* @param trits source trits array
174+
* @param offset starting position for trits
175+
* @param size amount of trits to convert
176+
* @return tryte string
177+
*/
178+
public static String trytes(final byte[] trits, final int offset, final int size) {
179+
final StringBuilder trytes = new StringBuilder();
180+
for (int i = 0; i < (size + NUMBER_OF_TRITS_IN_A_TRYTE - 1) / NUMBER_OF_TRITS_IN_A_TRYTE; i++) {
181+
int j = trits[offset + i * 3] + trits[offset + i * 3 + 1] * 3 + trits[offset + i * 3 + 2] * 9;
182+
if (j < 0) {
183+
j += TRYTE_ALPHABET.length();
184+
}
185+
trytes.append(TRYTE_ALPHABET.charAt(j));
186+
}
187+
return trytes.toString();
188+
}
189+
190+
/**
191+
* Converts trits (bytes array)to a tryte string.<br>
192+
* @see #trytes(byte[], int, int)
193+
*
194+
* @param trits source trits array
195+
* @return tryte string
196+
*/
197+
public static String trytes(final byte[] trits) {
198+
return trytes(trits, 0, trits.length);
199+
}
200+
201+
/**
202+
* Creates a new trits array with the converted tryte string.<br>
203+
* should be used only for testing as it allocates memory.
204+
* @see #allocatingTritsFromTrytes(String)
205+
* @see #trits(String, byte[], int)
206+
*
207+
* @param trytes source trytes string
208+
* @return a new trit array
209+
*/
210+
public static byte[] allocatingTritsFromTrytes(String trytes) {
211+
byte[] trits = allocateTritsForTrytes(trytes.length());
212+
trits(trytes, trits, 0);
213+
return trits;
214+
}
103215

216+
217+
// Long <-> Trits
218+
219+
/**
220+
* Parses the trits argument as a long value, based on <i>Balanced ternary</i> arithmetic
221+
* @param trits Array of trits to be parsed
222+
* @param srcPos Starting position in trits array
223+
* @param size Amount of trits to parse
224+
* @return the long value represented by the trits array
225+
*/
226+
public static long longValue(final byte[] trits, final int srcPos, final int size) {
227+
228+
long value = 0;
229+
for (int i = size; i-- > 0; ) {
230+
value = value * RADIX + trits[srcPos + i];
231+
}
232+
return value;
233+
}
234+
235+
/**
236+
* fills a trit array with a representation of the {@code value} argument in <i>Balanced ternary</i> arithmetic
237+
238+
* @param value a long value
239+
* @param destination destination trit array
240+
* @param offset starting position of destination array
241+
* @param size max amount of trits to fill
242+
*/
243+
public static void copyTrits(final long value, final byte[] destination, final int offset, final int size) {
104244
long absoluteValue = value < 0 ? -value : value;
105245
for (int i = 0; i < size; i++) {
106246

@@ -122,35 +262,31 @@ public static void copyTrits(final long value, final byte[] destination, final i
122262
}
123263

124264

125-
public static String trytes(final byte[] trits, final int offset, final int size) {
265+
// Additional conversions
126266

127-
final StringBuilder trytes = new StringBuilder();
128-
for (int i = 0; i < (size + NUMBER_OF_TRITS_IN_A_TRYTE - 1) / NUMBER_OF_TRITS_IN_A_TRYTE; i++) {
129-
int j = trits[offset + i * 3] + trits[offset + i * 3 + 1] * 3 + trits[offset + i * 3 + 2] * 9;
130-
if (j < 0) {
131-
j += TRYTE_ALPHABET.length();
267+
/**
268+
* Converts an {@code ASCII string} into a {@code TryteString} representation.
269+
* <p>
270+
* each ASCII character is converted to 2 Trytes.
271+
* </p>
272+
*
273+
* @param input ASCII string.
274+
* @return Trytes string
275+
*/
276+
public static String asciiToTrytes(String input) {
277+
StringBuilder sb = new StringBuilder(80);
278+
for (int i = 0; i < input.length(); i++) {
279+
int asciiValue = input.charAt(i);
280+
// If not recognizable ASCII character, return null
281+
if (asciiValue > 255) {
282+
return null;
132283
}
133-
trytes.append(TRYTE_ALPHABET.charAt(j));
134-
}
135-
return trytes.toString();
136-
}
137-
138-
public static String trytes(final byte[] trits) {
139-
return trytes(trits, 0, trits.length);
140-
}
141-
142-
public static int tryteValue(final byte[] trits, final int offset) {
143-
return trits[offset] + trits[offset + 1] * 3 + trits[offset + 2] * 9;
144-
}
145-
146-
public static Pair<byte[], byte[]> intPair(byte[] trits) {
147-
byte[] low = new byte[trits.length];
148-
byte[] hi = new byte[trits.length];
149-
for(int i = 0; i< trits.length; i++) {
150-
low[i] = trits[i] != (byte) 1 ? HIGH_INTEGER_BITS: (byte) 0;
151-
hi[i] = trits[i] != (byte) -1 ? HIGH_INTEGER_BITS: (byte) 0;
284+
int firstValue = asciiValue % 27;
285+
int secondValue = (asciiValue - firstValue) / 27;
286+
sb.append(TRYTE_ALPHABET.charAt(firstValue));
287+
sb.append(TRYTE_ALPHABET.charAt(secondValue));
152288
}
153-
return new Pair<>(low, hi);
289+
return sb.toString();
154290
}
155291

156292
public static Pair<long[], long[]> longPair(byte[] trits) {
@@ -163,19 +299,6 @@ public static Pair<long[], long[]> longPair(byte[] trits) {
163299
return new Pair<>(low, hi);
164300
}
165301

166-
public static void shiftPair(Pair<long[], long[]> source, Pair<long[], long[]> dest) {
167-
if(source.low.length == dest.low.length && source.hi.length == dest.hi.length) {
168-
for(int i = 0; i < dest.low.length; i++) {
169-
dest.low[i] <<= 1;
170-
dest.low[i] |= source.low[i] & 1;
171-
}
172-
for(int i = 0; i < dest.hi.length; i++) {
173-
dest.hi[i] <<= 1;
174-
dest.hi[i] |= source.hi[i] & 1;
175-
}
176-
}
177-
}
178-
179302
public static byte[] trits(final Pair<long[], long[]> pair, final int bitIndex) {
180303
final int length;
181304
if(pair.low.length == pair.hi.length || pair.low.length < pair.hi.length) {
@@ -216,36 +339,4 @@ public static byte[] trits(byte[] low, byte[] hi) {
216339
}
217340
return trits;
218341
}
219-
220-
private static void increment(final byte[] trits, final int size) {
221-
for (int i = 0; i < size; i++) {
222-
if (++trits[i] > Converter.MAX_TRIT_VALUE) {
223-
trits[i] = Converter.MIN_TRIT_VALUE;
224-
} else {
225-
break;
226-
}
227-
}
228-
}
229-
230-
public static String asciiToTrytes(String input) {
231-
StringBuilder sb = new StringBuilder(80);
232-
for (int i = 0; i < input.length(); i++) {
233-
int asciiValue = input.charAt(i);
234-
// If not recognizable ASCII character, return null
235-
if (asciiValue > 255) {
236-
return null;
237-
}
238-
int firstValue = asciiValue % 27;
239-
int secondValue = (asciiValue - firstValue) / 27;
240-
sb.append(TRYTE_ALPHABET.charAt(firstValue));
241-
sb.append(TRYTE_ALPHABET.charAt(secondValue));
242-
}
243-
return sb.toString();
244-
}
245-
246-
public static byte[] allocatingTritsFromTrytes(String trytes) {
247-
byte[] trits = allocateTritsForTrytes(trytes.length());
248-
trits(trytes, trits, 0);
249-
return trits;
250-
}
251342
}

0 commit comments

Comments
 (0)