有什么方法可以使用 Guava 获取 InputStream 的哈希码吗?

Is there any way to get the hashcode of an InputStream using Guava?

有没有办法获取 Java 中 InputStream 的 HashCode, 我正在尝试使用 PrimeFaces 中的 <p:fileUpload/> 上传图片,将其转换为 HashCode 并将其与另一张图片进行比较。

目前我正在尝试这个:

public void save(FileUploadEvent event) throws IOException {
        HashCode hashCode = null;
        HashCode hashCodeCompare = null;
        hashCode = Files.asByteSource(new File(event.toString())).hash(Hashing.murmur3_128(50));
        hashCodeCompare = Files.asByteSource(new File(FilePathOfFileToCompare)).hash(Hashing.murmur3_128(50));
        boolean hashTrueFalse;
        if(hashCode.equals(hashCodeCompare)) {
            System.out.println("true");
        } else{
            System.out.println("false");
        }

        try (InputStream input = event.getFile().getInputstream()) {
            String imageName = generateFileName() + "." + fileExtensions(event.getFile().getFileName());
            String imageLink = PICTURE_DESTINATION + "\" + imageName;


            Picture picture = new Picture();
            picture.setPictureUrl(imageLink);
            pictureService.createOrUpdate(picture);

            personForm.getCurrentPersonDTO().setPictureDTO(pictureMapper.toDTO(picture));


        } catch (IOException e) {
            e.printStackTrace();
        }
    }

有什么方法可以将 InputStream 变成哈希码吗?

如果你要计算它包含的字节的散列,你必须阅读 InputStream。首先读取 InputSteam 到一个 byte[]。

对于 Guava 使用 ByteStreams:

InputStream in = ...;
byte[] bytes = ByteStreams.toByteArray(in);

另一种流行的方法是使用 Commons IO:

InputStream in = ...;
byte[] bytes = IOUtils.toByteArray(in);

然后你可以在字节数组上调用Arrays.hashCode():

int hash = java.util.Arrays.hashCode(bytes);

但是您可能会考虑使用 SHA256 作为您的哈希函数,因为您不太可能发生冲突:

MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] sha256Hash = digest.digest(bytes);

如果您不想将整个流读取到内存字节数组中,您可以在其他人读取 InputStream 时计算哈希。例如,您可能希望将 InputStream 流式传输到磁盘到数据库中。 Guava 提供了一个 class 包装了一个 InputStream 为你做这个 HashingInputStream:

首先用 HashinInputStream 包装你的 InputStream

HashingInputStream hin = new HashingInputStream(Hashing.sha256(), in);

然后让 HashingInputStream 以您喜欢的任何方式读取

while(hin.read() != -1);

然后从 HashingInputStream 获取哈希值

byte[] sha256Hash = hin.hash().asBytes();

你想要做的是 ByteStreams.copy(input, Funnels.asOutputStream(hasher)) 其中 hasher 是从例如Hashing.sha256().newHasher()。然后,调用 hasher.hash() 得到结果 HashCode.

我建议使用 Files.asByteSource(fileSource.getFile()).hash(hashFunction).padToLong()