Это работает для загрузки и установки фонового изображения панели содержимого:
jar (или путь сборки) содержит:
- com
- img
---- bg.png
java содержит:
JFrame f = new JFrame("Testing load resource from jar");
try {
BufferedImage bg = ImageIO.read(getClass().getResource("/img/bg.png"));
f.setContentPane(new ImagePanel(bg));
} catch (IOException e) {
e.printStackTrace();
}
Протестировано и работает как в jar, так и в unjarred (это технический термин).
BTW getClass().getClassLoader().getResourceAsStream("/img/bg.png")
- который я пробовал в первую очередь, возвратил мне null InputStream.
Простой подход должен был бы проверить, сколько цифр производится Integer.toHexString()
и добавляет начальный нуль к каждому байту в случае необходимости. Что-то вроде этого:
public static String toHexString(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xFF & bytes[i]);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
Это, что я использую для хешей MD5:
public static String getMD5(String filename)
throws NoSuchAlgorithmException, IOException {
MessageDigest messageDigest =
java.security.MessageDigest.getInstance("MD5");
InputStream in = new FileInputStream(filename);
byte [] buffer = new byte[8192];
int len = in.read(buffer, 0, buffer.length);
while (len > 0) {
messageDigest.update(buffer, 0, len);
len = in.read(buffer, 0, buffer.length);
}
in.close();
return new BigInteger(1, messageDigest.digest()).toString(16);
}
РЕДАКТИРОВАНИЕ: я протестировал, и я заметил, что с этим также конечные нули сокращаются. Но это может только произойти в начале, таким образом, можно соответствовать ожидаемой длине и клавиатуре соответственно.
byte messageDigest[] = algorithm.digest();
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++) {
String hexByte = Integer.toHexString(0xFF & messageDigest[i]);
int numDigits = 2 - hexByte.length();
while (numDigits-- > 0) {
hexString.append('0');
}
hexString.append(hexByte);
}
Это решение является немного более старой школой и должно быть эффективной памятью.
public static String toHexString(byte bytes[]) {
if (bytes == null) {
return null;
}
StringBuffer sb = new StringBuffer();
for (int iter = 0; iter < bytes.length; iter++) {
byte high = (byte) ( (bytes[iter] & 0xf0) >> 4);
byte low = (byte) (bytes[iter] & 0x0f);
sb.append(nibble2char(high));
sb.append(nibble2char(low));
}
return sb.toString();
}
private static char nibble2char(byte b) {
byte nibble = (byte) (b & 0x0f);
if (nibble < 10) {
return (char) ('0' + nibble);
}
return (char) ('a' + nibble - 10);
}
String result = String.format("%0" + messageDigest.length + "s", hexString.toString())
Это - самое короткое решение, данное, что Вы уже имеете. Если Вы могли бы преобразовать массив байтов в числовое значение, String.format
может преобразовать его в шестнадцатеричную строку одновременно.
Apache выезда Кодек палаты общин Hex.encodeHex. Тип возврата char[]
, который может тривиально быть преобразован в String
. Так:
import org.apache.commons.codec.binary;
Hex.encodeHexString(messageDigest);
Вы можете использовать приведенный ниже. Я тестировал это с начальными нулевыми байтами и с начальными отрицательными байтами
public static String toHex(byte[] bytes) {
BigInteger bi = new BigInteger(1, bytes);
return String.format("%0" + (bytes.length << 1) + "X", bi);
}
Если вам нужны шестнадцатеричные цифры в нижнем регистре, используйте «x»
в формате String.
Другой option
public static String toHexString(byte[]bytes) {
StringBuilder sb = new StringBuilder(bytes.length*2);
for(byte b: bytes)
sb.append(Integer.toHexString(b+0x800).substring(1));
return sb.toString();
}
Я обнаружил, что Integer.toHexString работает немного медленнее. Если вы конвертируете много байтов, вы можете подумать о создании массива строк, содержащих «00» .. «FF», и использовать целое число в качестве индекса. Т.е.
hexString.append(hexArray[0xFF & messageDigest[i]]);
Это быстрее и обеспечивает правильную длину. Просто требуется массив строк:
String[] hexArray = {
"00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",
"10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",
"20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
"30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",
"40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",
"50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
"60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",
"70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",
"80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
"90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",
"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",
"B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
"C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",
"D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",
"E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",
"F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF"};
Я искал то же самое ... здесь есть несколько хороших идей, но я провел несколько микротестов. Я обнаружил, что следующее является самым быстрым (изменено по сравнению с описанием Аймана выше и примерно в 2 раза быстрее, и примерно на 50% быстрее, чем у Стива чуть выше этого):
public static String hash(String text, String algorithm)
throws NoSuchAlgorithmException {
byte[] hash = MessageDigest.getInstance(algorithm).digest(text.getBytes());
return new BigInteger(1, hash).toString(16);
}
Редактировать: Упс - пропустил, что это по сути то же самое, что и у Кгианнакакиса и так может удалить начальный 0. Тем не менее, изменив это на следующее, он все равно самый быстрый:
public static String hash(String text, String algorithm)
throws NoSuchAlgorithmException {
byte[] hash = MessageDigest.getInstance(algorithm).digest(text.getBytes());
BigInteger bi = new BigInteger(1, hash);
String result = bi.toString(16);
if (result.length() % 2 != 0) {
return "0" + result;
}
return result;
}
Похоже, функции concat и append могут работать очень медленно. Следующее было НАМНОГО быстрее для меня (чем мой предыдущий пост). Переход на массив символов при построении вывода был ключевым фактором для его ускорения. Я не сравнивал с Hex.encodeHex, предложенным Брэндоном Дюретте.
public static String toHexString(byte[] bytes) {
char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] hexChars = new char[10000000];
int c = 0;
int v;
for ( j = 0; j < bytes.length; j++ ) {
v = bytes[j] & 0xFF;
hexChars[c] = hexArray[v/16];
c++;
hexChars[c] = hexArray[v%16];
c++;
}
return new String(hexChars, 0, c); }
Мне понравились материалы Стива, но он мог бы обойтись без пары переменных и сохранил несколько строк в процессе.
public static String toHexString(byte[] bytes) {
char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] hexChars = new char[bytes.length * 2];
int v;
for ( int j = 0; j < bytes.length; j++ ) {
v = bytes[j] & 0xFF;
hexChars[j*2] = hexArray[v/16];
hexChars[j*2 + 1] = hexArray[v%16];
}
return new String(hexChars);
}
Что мне нравится в этом, так это то, что легко увидеть, что именно он делает (вместо того, чтобы полагаться на какое-то волшебное преобразование BigInteger в черный ящик), и вам также не нужно беспокоиться о угловых случаях, таких как ведущие нули и т. Эта процедура принимает каждый 4-битный полубайт и превращает его в шестнадцатеричный символ. И он использует поиск по таблице, так что, вероятно, это быстро. Вероятно, это могло бы быть быстрее, если бы вы заменили v / 16 и v% 16 на битовые сдвиги и AND, но мне лень тестировать это прямо сейчас.
static String toHex(byte[] digest) {
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%1$02X", b));
}
return sb.toString();
}
Чтобы сохранить ведущие нули, вот небольшой вариант того, что предложил Пол (например, хеш md5):
public static String MD5hash(String text) throws NoSuchAlgorithmException {
byte[] hash = MessageDigest.getInstance("MD5").digest(text.getBytes());
return String.format("%032x",new BigInteger(1, hash));
}
Ой, это выглядит хуже, чем то, что предлагал Айман, извините за это