001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.util;
007:
008: import java.sql.SQLException;
009:
010: import org.h2.constant.ErrorCode;
011: import org.h2.message.Message;
012:
013: /**
014: * This utility class contains functions related to byte arrays.
015: */
016: public class ByteUtils {
017:
018: private static final char[] HEX = "0123456789abcdef".toCharArray();
019:
020: public static int readInt(byte[] buff, int pos) {
021: return (buff[pos++] << 24) + ((buff[pos++] & 0xff) << 16)
022: + ((buff[pos++] & 0xff) << 8) + (buff[pos++] & 0xff);
023: }
024:
025: public static long readLong(byte[] buff, int pos) {
026: return ((long) (readInt(buff, pos)) << 32)
027: + (readInt(buff, pos + 4) & 0xffffffffL);
028: }
029:
030: public static int indexOf(byte[] bytes, byte[] pattern, int start) {
031: if (pattern.length == 0) {
032: return start;
033: }
034: if (start > bytes.length) {
035: return -1;
036: }
037: int last = bytes.length - pattern.length + 1;
038: next: for (; start < last; start++) {
039: for (int i = 0; i < pattern.length; i++) {
040: if (bytes[start + i] != pattern[i]) {
041: continue next;
042: }
043: }
044: return start;
045: }
046: return -1;
047: }
048:
049: public static byte[] convertStringToBytes(String s)
050: throws SQLException {
051: int len = s.length();
052: if (len % 2 != 0) {
053: throw Message
054: .getSQLException(ErrorCode.HEX_STRING_ODD_1, s);
055: }
056: len /= 2;
057: byte[] buff = new byte[len];
058: for (int i = 0; i < len; i++) {
059: buff[i] = (byte) ((getHexDigit(s, i + i) << 4) | getHexDigit(
060: s, i + i + 1));
061: }
062: return buff;
063: }
064:
065: private static int getHexDigit(String s, int i) throws SQLException {
066: char c = s.charAt(i);
067: if (c >= '0' && c <= '9') {
068: return c - '0';
069: } else if (c >= 'a' && c <= 'f') {
070: return c - 'a' + 0xa;
071: } else if (c >= 'A' && c <= 'F') {
072: return c - 'A' + 0xa;
073: } else {
074: throw Message.getSQLException(ErrorCode.HEX_STRING_WRONG_1,
075: s);
076: }
077: }
078:
079: public static int getByteArrayHash(byte[] value) {
080: int h = 1;
081: for (int i = 0; i < value.length;) {
082: h = 31 * h + value[i++];
083: }
084: return h;
085: }
086:
087: public static String convertBytesToString(byte[] value) {
088: return convertBytesToString(value, value.length);
089: }
090:
091: public static String convertBytesToString(byte[] value, int len) {
092: char[] buff = new char[len + len];
093: char[] hex = HEX;
094: for (int i = 0; i < len; i++) {
095: int c = value[i] & 0xff;
096: buff[i + i] = hex[c >> 4];
097: buff[i + i + 1] = hex[c & 0xf];
098: }
099: return new String(buff);
100: }
101:
102: public static boolean compareSecure(byte[] test, byte[] good) {
103: if ((test == null) || (good == null)) {
104: return (test == null) && (good == null);
105: }
106: if (test.length != good.length) {
107: return false;
108: }
109: if (test.length == 0) {
110: return true;
111: }
112: // silly loop: this should help a little against timing attacks
113: boolean correct = true, correct2 = false;
114: for (int i = 0; i < good.length; i++) {
115: if (test[i] != good[i]) {
116: correct = false;
117: } else {
118: correct2 = true;
119: }
120: }
121: return correct && correct2;
122: }
123:
124: public static void clear(byte[] buff) {
125: for (int i = 0; i < buff.length; i++) {
126: buff[i] = 0;
127: }
128: }
129:
130: public static int compareNotNull(byte[] data1, byte[] data2) {
131: int len = Math.min(data1.length, data2.length);
132: for (int i = 0; i < len; i++) {
133: byte b = data1[i];
134: byte b2 = data2[i];
135: if (b != b2) {
136: return b > b2 ? 1 : -1;
137: }
138: }
139: int c = data1.length - data2.length;
140: return c == 0 ? 0 : (c < 0 ? -1 : 1);
141: }
142:
143: public static String convertToBinString(byte[] buff) {
144: char[] chars = new char[buff.length];
145: for (int i = 0; i < buff.length; i++) {
146: chars[i] = (char) (buff[i] & 0xff);
147: }
148: return new String(chars);
149: }
150:
151: public static byte[] convertBinStringToBytes(String data) {
152: byte[] buff = new byte[data.length()];
153: for (int i = 0; i < data.length(); i++) {
154: buff[i] = (byte) (data.charAt(i) & 0xff);
155: }
156: return buff;
157: }
158:
159: public static byte[] copy(byte[] source, byte[] target) {
160: int len = source.length;
161: if (len > target.length) {
162: target = new byte[len];
163: }
164: System.arraycopy(source, 0, target, 0, len);
165: return target;
166: }
167:
168: public static byte[] cloneByteArray(byte[] b) {
169: int len = b.length;
170: if (len == 0) {
171: return b;
172: }
173: byte[] copy = new byte[len];
174: System.arraycopy(b, 0, copy, 0, len);
175: return copy;
176: }
177:
178: }
|