Coverage Summary for Class: Utils (org.ethereum.util)
Class |
Class, %
|
Method, %
|
Line, %
|
Utils |
0%
(0/1)
|
0%
(0/24)
|
0%
(0/98)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2017 RSK Labs Ltd.
4 * (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>)
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package org.ethereum.util;
21
22 import org.bouncycastle.util.encoders.DecoderException;
23 import org.bouncycastle.util.encoders.Hex;
24
25 import java.lang.reflect.Array;
26 import java.math.BigInteger;
27 import java.nio.charset.StandardCharsets;
28 import java.security.SecureRandom;
29 import java.text.DateFormat;
30 import java.text.SimpleDateFormat;
31 import java.util.Arrays;
32 import java.util.Date;
33 import java.util.List;
34 import java.util.regex.Pattern;
35
36
37 public class Utils {
38
39 private static SecureRandom random = new SecureRandom();
40
41 /**
42 * @param number should be in form '0x34fabd34....'
43 * @return String
44 */
45 public static BigInteger unifiedNumericToBigInteger(String number) {
46
47 boolean match = Pattern.matches("0[xX][0-9a-fA-F]+", number);
48 if (!match) {
49 return (new BigInteger(number));
50 } else{
51 number = number.substring(2);
52 number = number.length() % 2 != 0 ? "0".concat(number) : number;
53 byte[] numberBytes = Hex.decode(number);
54 return (new BigInteger(1, numberBytes));
55 }
56 }
57
58 /**
59 * Return formatted Date String: yyyy.MM.dd HH:mm:ss
60 * Based on Unix's time() input in seconds
61 *
62 * @param timestamp seconds since start of Unix-time
63 * @return String formatted as - yyyy.MM.dd HH:mm:ss
64 */
65 public static String longToDateTime(long timestamp) {
66 Date date = new Date(timestamp * 1000);
67 DateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
68 return formatter.format(date);
69 }
70
71 static BigInteger _1000_ = new BigInteger("1000");
72
73 public static String getValueShortString(BigInteger number) {
74 BigInteger result = number;
75 int pow = 0;
76 while (result.compareTo(_1000_) == 1 || result.compareTo(_1000_) == 0) {
77 result = result.divide(_1000_);
78 pow += 3;
79 }
80 return result.toString() + "ยท(" + "10^" + pow + ")";
81 }
82
83 /**
84 * Decodes a hex string to address bytes and checks validity
85 *
86 * @param hex - a hex string of the address, e.g., 6c386a4b26f73c802f34673f7248bb118f97424a
87 * @return - decode and validated address byte[]
88 */
89 public static byte[] addressStringToBytes(String hex) {
90 final byte[] addr;
91 try {
92 addr = Hex.decode(hex);
93 } catch (DecoderException addressIsNotValid) {
94 return null;
95 }
96
97 if (isValidAddress(addr)) {
98 return addr;
99 }
100 return null;
101 }
102
103 public static boolean isValidAddress(byte[] addr) {
104 return addr != null && addr.length == 20;
105 }
106
107 /**
108 * @param addr length should be 20
109 * @return short string represent 1f21c...
110 */
111 public static String getAddressShortString(byte[] addr) {
112
113 if (!isValidAddress(addr)) {
114 throw new Error("not an address");
115 }
116
117 String addrShort = ByteUtil.toHexString(addr, 0, 3);
118
119 StringBuffer sb = new StringBuffer();
120 sb.append(addrShort);
121 sb.append("...");
122
123 return sb.toString();
124 }
125
126 public static SecureRandom getRandom() {
127 return random;
128 }
129
130 public static final double JAVA_VERSION = getJavaVersion();
131
132 static double getJavaVersion() {
133 String version = System.getProperty("java.version");
134
135 // on android this property equals to 0
136 if (version.equals("0")) {
137 return 0;
138 }
139
140 int pos = 0;
141 int count = 0;
142
143 for (; pos < version.length() && count < 2; pos++) {
144 if (version.charAt(pos) == '.') {
145 count++;
146 }
147 }
148 return Double.parseDouble(version.substring(0, pos - 1));
149 }
150
151 public static String getHashListShort(List<byte[]> blockHashes) {
152 if (blockHashes.isEmpty()) {
153 return "[]";
154 }
155
156 StringBuilder sb = new StringBuilder();
157 String firstHash = ByteUtil.toHexString(blockHashes.get(0));
158 String lastHash = ByteUtil.toHexString(blockHashes.get(blockHashes.size() - 1));
159 return sb.append(" ").append(firstHash).append("...").append(lastHash).toString();
160 }
161
162 public static long toUnixTime(long javaTime) {
163 return javaTime / 1000;
164 }
165
166 public static long fromUnixTime(long unixTime) {
167 return unixTime * 1000;
168 }
169
170 public static <T> T[] mergeArrays(T[] ... arr) {
171 int size = 0;
172 for (T[] ts : arr) {
173 size += ts.length;
174 }
175 T[] ret = (T[]) Array.newInstance(arr[0].getClass().getComponentType(), size);
176 int off = 0;
177 for (T[] ts : arr) {
178 System.arraycopy(ts, 0, ret, off, ts.length);
179 off += ts.length;
180 }
181 return ret;
182 }
183
184 public static String align(String s, char fillChar, int targetLen, boolean alignRight) {
185 if (targetLen <= s.length()) {
186 return s;
187 }
188 String alignString = repeat("" + fillChar, targetLen - s.length());
189 return alignRight ? alignString + s : s + alignString;
190
191 }
192 public static String repeat(String s, int n) {
193 if (s.length() == 1) {
194 byte[] bb = new byte[n];
195 Arrays.fill(bb, s.getBytes(StandardCharsets.UTF_8)[0]);
196 return new String(bb);
197 } else {
198 StringBuilder ret = new StringBuilder();
199 for (int i = 0; i < n; i++) {
200 ret.append(s);
201 }
202 return ret.toString();
203 }
204 }
205
206 public static boolean contains(List<byte[]> list, byte[] valueToFind) {
207 for (byte[] b : list) {
208 if (Arrays.equals(b, valueToFind)) {
209 return true;
210 }
211 }
212
213 return false;
214 }
215
216 public static void validateArrayAllegedSize(byte[] data, int offset, int allegedSize) {
217 if (data.length < Math.addExact(allegedSize, offset)) {
218 throw new IllegalArgumentException("The specified size exceeds the size of the payload");
219 }
220 }
221
222 public static byte[] safeCopyOfRange(byte[] data, int from, int size) {
223 validateArrayAllegedSize(data, from, size);
224 return Arrays.copyOfRange(data, from, from + size);
225 }
226
227 public static boolean isDecimalString(String s) {
228 return s.matches("^\\d+$");
229 }
230
231 public static boolean isHexadecimalString(String s) {
232 return s.matches("^0x[\\da-fA-F]+$");
233 }
234
235 public static long decimalStringToLong(String s) {
236 try {
237 return Long.parseLong(s, 10);
238 } catch (NumberFormatException e) {
239 throw new IllegalArgumentException(String.format("Invalid decimal number: %s", s), e);
240 }
241 }
242
243 public static long hexadecimalStringToLong(String s) {
244 if (!s.startsWith("0x")) {
245 throw new IllegalArgumentException(String.format("Invalid hexadecimal number: %s", s));
246 }
247
248 try {
249 // Remove leading '0x' before parsing
250 return Long.parseLong(s.substring(2), 16);
251 } catch (NumberFormatException e) {
252 throw new IllegalArgumentException(String.format("Invalid hexadecimal number: %s", s), e);
253 }
254 }
255
256 public static int significantBitCount(int number) {
257 int result = 0;
258 while (number > 0) {
259 result++;
260 number >>= 1;
261 }
262 return result;
263 }
264 }