blob: 2f8a6791764ecf13da7f7a420e63b49273917b23 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
Thomas Vachuska24c849c2014-10-27 09:53:05 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska24c849c2014-10-27 09:53:05 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
weibit38c42ed2014-10-09 19:03:54 -070016package org.onlab.util;
17
18public final class HexString {
19
Yuta HIGUCHI65849892017-08-18 13:09:41 -070020 private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
21
weibit38c42ed2014-10-09 19:03:54 -070022 private HexString() {
weibit38c42ed2014-10-09 19:03:54 -070023 }
24
25 /**
Charles Chan2340c792015-11-26 19:41:51 -080026 * Convert a byte array to a colon-separated hex string.
weibit38c42ed2014-10-09 19:03:54 -070027 *
Charles Chan2340c792015-11-26 19:41:51 -080028 * @param bytes byte array to be converted
29 * @return converted colon-separated hex string, e.g. "0f:ca:fe:de:ad:be:ef",
30 * or "(null)" if given byte array is null
weibit38c42ed2014-10-09 19:03:54 -070031 */
32 public static String toHexString(final byte[] bytes) {
Charles Chan2340c792015-11-26 19:41:51 -080033 return toHexString(bytes, ":");
34 }
35
36 /**
37 * Convert a byte array to a hex string separated by given separator.
38 *
39 * @param bytes byte array to be converted
40 * @param separator the string use to separate each byte
41 * @return converted hex string, or "(null)" if given byte array is null
42 */
43 public static String toHexString(final byte[] bytes, String separator) {
Yuta HIGUCHI6b38ee32014-11-14 02:02:59 -080044 if (bytes == null) {
45 return "(null)";
46 }
Charles Chan2340c792015-11-26 19:41:51 -080047 if (separator == null) {
48 separator = "";
49 }
Yuta HIGUCHI65849892017-08-18 13:09:41 -070050 int slen = bytes.length * (2 + separator.length()) - separator.length();
51 StringBuilder ret = new StringBuilder(slen);
52 boolean addSeparator = !separator.isEmpty();
53 for (int i = 0; i < bytes.length; i++) {
54 if (i > 0 && addSeparator) {
Charles Chan2340c792015-11-26 19:41:51 -080055 ret.append(separator);
weibit38c42ed2014-10-09 19:03:54 -070056 }
Yuta HIGUCHI65849892017-08-18 13:09:41 -070057 ret.append(HEX_CHARS[(bytes[i] >> 4) & 0xF]);
58 ret.append(HEX_CHARS[(bytes[i] & 0xF)]);
weibit38c42ed2014-10-09 19:03:54 -070059 }
60 return ret.toString();
61 }
62
Charles Chan2340c792015-11-26 19:41:51 -080063 /**
64 * Convert a long number to colon-separated hex string.
65 * Prepend zero padding until given length.
66 *
67 * @param val long number to be converted
68 * @param padTo prepend zeros until this length
69 * @return converted colon-separated hex string, e.g. "0f:ca:fe:de:ad:be:ef"
70 */
weibit38c42ed2014-10-09 19:03:54 -070071 public static String toHexString(final long val, final int padTo) {
72 char[] arr = Long.toHexString(val).toCharArray();
Yuta HIGUCHIe5ca93b2014-10-23 09:49:00 -070073 StringBuilder ret = new StringBuilder(padTo * 3 - 1);
weibit38c42ed2014-10-09 19:03:54 -070074 // prepend the right number of leading zeros
75 int i = 0;
76 for (; i < (padTo * 2 - arr.length); i++) {
Yuta HIGUCHIe5ca93b2014-10-23 09:49:00 -070077 ret.append('0');
weibit38c42ed2014-10-09 19:03:54 -070078 if ((i % 2) != 0) {
Yuta HIGUCHIe5ca93b2014-10-23 09:49:00 -070079 ret.append(':');
weibit38c42ed2014-10-09 19:03:54 -070080 }
81 }
82 for (int j = 0; j < arr.length; j++) {
Yuta HIGUCHIe5ca93b2014-10-23 09:49:00 -070083 ret.append(arr[j]);
weibit38c42ed2014-10-09 19:03:54 -070084 if ((((i + j) % 2) != 0) && (j < (arr.length - 1))) {
Yuta HIGUCHIe5ca93b2014-10-23 09:49:00 -070085 ret.append(':');
weibit38c42ed2014-10-09 19:03:54 -070086 }
87 }
Yuta HIGUCHIe5ca93b2014-10-23 09:49:00 -070088 return ret.toString();
weibit38c42ed2014-10-09 19:03:54 -070089 }
90
Charles Chan2340c792015-11-26 19:41:51 -080091 /**
92 * Convert a long number to colon-separated hex string.
93 * Prepend zero padding until 8 bytes.
94 *
95 * @param val long number to be converted
96 * @return converted colon-separated hex string, e.g. "0f:ca:fe:de:ad:be:ef"
97 */
weibit38c42ed2014-10-09 19:03:54 -070098 public static String toHexString(final long val) {
99 return toHexString(val, 8);
100 }
101
102 /**
Charles Chan2340c792015-11-26 19:41:51 -0800103 * Convert a colon-separated hex string to byte array.
weibit38c42ed2014-10-09 19:03:54 -0700104 *
Charles Chan2340c792015-11-26 19:41:51 -0800105 * @param values colon-separated hex string to be converted,
106 * e.g. "0f:ca:fe:de:ad:be:ef"
107 * @return converted byte array
108 * @throws NumberFormatException if input hex string cannot be parsed
weibit38c42ed2014-10-09 19:03:54 -0700109 */
110 public static byte[] fromHexString(final String values) {
Carmelo Cascone6d9ab3a2016-05-31 11:25:58 -0700111 return fromHexString(values, ":");
112 }
113
114 /**
115 * Convert a hex-string with arbitrary separator to byte array.
116 * If separator is the empty string or null, then no separator will be considered.
117 *
118 * @param values hex string to be converted
Ray Milkeybb23e0b2016-08-02 17:00:21 -0700119 * @param separator regex for separator
Carmelo Cascone6d9ab3a2016-05-31 11:25:58 -0700120 * @return converted byte array
121 * @throws NumberFormatException if input hex string cannot be parsed
122 */
123 public static byte[] fromHexString(final String values, String separator) {
124 String regexSeparator;
125 if (separator == null || separator.length() == 0) {
126 regexSeparator = "(?<=\\G.{2})"; // Split string into several two character strings
127 } else {
128 regexSeparator = separator;
129 }
130 String[] octets = values.split(regexSeparator);
weibit38c42ed2014-10-09 19:03:54 -0700131 byte[] ret = new byte[octets.length];
132
133 for (int i = 0; i < octets.length; i++) {
134 if (octets[i].length() > 2) {
135 throw new NumberFormatException("Invalid octet length");
136 }
137 ret[i] = Integer.valueOf(octets[i], 16).byteValue();
138 }
139 return ret;
140 }
141
Charles Chan2340c792015-11-26 19:41:51 -0800142 /**
143 * Convert a colon-separated hex string to long.
144 *
145 * @param value colon-separated hex string to be converted,
146 * e.g. "00:0f:ca:fe:de:ad:be:ef"
147 * @return converted long number
148 * @throws NumberFormatException if input hex string cannot be parsed
149 */
weibit38c42ed2014-10-09 19:03:54 -0700150 public static long toLong(String value) {
151 String[] octets = value.split(":");
152 if (octets.length > 8) {
153 throw new NumberFormatException("Input string is too big to fit in long: " + value);
154 }
155 long l = 0;
156 for (String octet: octets) {
157 if (octet.length() > 2) {
158 throw new NumberFormatException(
159 "Each colon-separated byte component must consist of 1 or 2 hex digits: " + value);
160 }
161 short s = Short.parseShort(octet, 16);
162 l = (l << 8) + s;
163 }
164 return l;
165 }
166}