Я хочу сравнить содержимое в cis и resStream. Моя цель - проверить, дало ли мне повторное шифрование те же данные или разные.
Любые зацепки были бы действительно замечательными. Спасибо
final InputStream cis = test.getEncryptingInputStream(is);
final InputStream resStream = test.reEncrypt(cis, "");
Как мы можем проверить содержимое InputStreams?
Вызовите read() для каждого и прекратите чтение, как только два вызова дадут разные значения. Вы можете сократить путь, вернув false, если файлы (если они файлы) различаются по длине.
Читать весь поток, md5 его, если хеши разные - контент другой.




Как сравнить содержимое 2 InputStreams объектов?
Вы можете прочитать данные из каждого потока и сравнить их байтовые коды. Не то, чтобы если потоки имеют разный размер, то они определенно не равны.
int cisByte = cis.read();
int resByte = resStream.read();
while (cisByte != -1 && resByte != -1) {
if (cisByte != resByte) {
return false;
}
cisByte = cis.read();
resByte = resStream.read();
}
return cisByte == resByte;
Я уверен, что test.reEncrypt(cis, "") уже читал бы стрим cis внутри него. Вот как это вернет reStream. Таким образом, вышеуказанная функция для чтения обоих одновременно не будет работать. Когда вы читаете из resStream для внутреннего шифрования байта, он также будет считываться из cis. Таким образом, из cis будет прочитано 2 байта (один с помощью вышеуказанной функции и один с помощью resStream.read() внутри), а из resByte только один. Зависит от того, как работает алгоритм. Но это в основном не сработает.
Есть ли способ преобразовать содержимое в inputStream в строку, чтобы я мог сравнить обе строки, если они равны или нет.
@priyanka Да, вы можете использовать «BufferedReader». Что-то вроде "BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));" и 'Построитель StringBuilder = новый StringBuilder();' затем поместите билдер в плавленный цикл, например, while, и вызовите «добавить», не стесняйтесь задавать другой вопрос об этом, если вам нужна дополнительная информация об этом.
Спасибо всем за быстрые ответы.
Если у вас есть два файла, то boolean identical = (Files.mismatch(path1, path2) == -1);
Apache Commons IO имеет этот метод: commons.apache.org/proper/commons-io/apidocs/org/apache/commons/…
Идея состоит в том, чтобы прочитать весь поток как строку, затем md5 строку и, наконец, проверить, совпадают ли хэши. MD5 гарантирует, что хеширование одной и той же строки даст тот же результат.
public String readInputStreamAsString(InputStream stream) {
int bufferSize = 1024;
char[] buffer = new char[bufferSize];
StringBuilder out = new StringBuilder();
Reader in = new InputStreamReader(stream, StandardCharsets.UTF_8);
for (int numRead; (numRead = in.read(buffer, 0, buffer.length)) > 0; ) {
out.append(buffer, 0, numRead);
}
return out.toString();
}
public String hashMD5(String input) {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(input.getBytes());
BigInteger number = new BigInteger(1, messageDigest);
String hashtext = number.toString(16);
return hashtext;
}
public void TestMe() {
final InputStream cis = test.getEncryptingInputStream(is);
final InputStream resStream = test.reEncrypt(cis, "");
String cisAsString = readInputStreamAsString(cis);
String resStreamAsString = readInputStreamAsString(resStream);
String cisMD5 = hashMD5(cisAsString);
String resMD5 = hashMD5(resStreamAsString);
if (cisMD5.equals(resMD5)) {
System.out.println("Streams contents are equal");
} else {
System.out.println("Stream contents are NOT equal :(");
}
}
Конечно, быстрее просто сравнить две строки, чем вычислять хэш, а затем сравнивать хэш? И тогда нет никаких шансов, что две разные строки хешируют одно и то же значение.
Для бесконечно длинной строки - конечно, сравнение отдельных символов - это путь. Для 10 мегабайт тестовых данных - есть ли разница? Я думал, что весь смысл вопроса в том, чтобы определить, есть ли разница, а не где она. Идентичные строки обязательно будут хэшироваться до одного и того же значения. Разные строки (следовательно, разное содержимое) не будут хешироваться до одного и того же значения.
@tgdavies смотри: My target is to check if the reEncryption gave me the same data or different.. Это делает это просто отлично. Возможно, неоптимальным способом, но простым способом.
Вы сделали решение более медленным, менее надежным и более сложным без какой-либо выгоды. Выражение cisMD5.equals(resMD5) может быть просто cisAsString.equals(resStreamAsString)
@tgdavies Надежность в стороне, разве это не демонстрирует идею сравнения двух вещей? Улучшение и оптимизация оставлены читателю в качестве упражнения :) Что, вероятно, для начала пропустит все чтение в строку.
Кто сказал что-нибудь о Strings?
Это приведет к сравнению с потерями, поскольку не все комбинации байтов допустимы в UTF-8 и приводят к замене символов Unicode (не говоря уже о том, что неквалифицированное использование String.getBytes() также может привести к потерям, если набор символов JVM по умолчанию не UTF-8), поэтому два разных потока могут создавать одну и ту же строку. Если вы хотите определить хэш, используйте DigestInputStream и прочитайте его (отбрасывая байты).
Ставлю только алгоритм, а не реальную реализацию...
final InputStream cis = test.getEncryptingInputStream(is);
Create a ByteArrayOutputStream cisArray / FileOutputStream
Read everything from cis and store in cisArray/FileOutputStream.
Create cisInputStream as ByteArrayInputStream from stored cisArray's bytes OR FileInputStream from file.
final InputStream resStream = test.reEncrypt(cisInputStream, "");
Read resStream & cisInputStream (re-open) byte by byte and compare
Зачем тебе все читать в память?
По крайней мере, один поток - cis должен быть прочитан в память и сохранен для последующего сравнения с выводом reEncrypt. Чтение resStream может выполняться побайтно и сравниваться с cisArray. Но, по крайней мере, cisArray нужно прочитать полностью и запомнить.
И зависит, вывод test.getEncryptingInputStream(is) тоже можно сохранить в файл, если памяти слишком много. Суть в том, что мы должны полностью прочитать один поток и где-то сохранить, а затем создать другой поток из этих сохраненных данных (в памяти или на диске) и передать его функции reEncrypt. Если мы напрямую передадим вывод getEncryptingInputStream в reEncrypt, это не сработает. Вы не можете прочитать первый вывод дважды. Вывод reEncrypt не нужно нигде хранить, а просто сравнить с сохраненным выводом getEncryptingInputStream
InputStreamимеетreadметод. Начните с этого, попробуйте реализовать, а если застрянете, задайте новый вопрос с конкретными деталями.