Java 如何散列文件以确定是否已看到它

Java 如何散列文件以确定是否已看到它,java,file,hash,Java,File,Hash,我正在开发一个web应用程序(使用JavaEE6和GF3.1),允许用户上传pdf文件。由于这是一个封闭的小社区,上传的文件很可能已经在系统中。我不能只检查名称是否重复,因为这显然是不够的。我在考虑散列整个文件并将条目存储在数据库中。这是否可行,如何实现?如果没有,那么还有什么更好的方法 考虑使用校验和 这是从 编辑: 请注意,校验和不能绝对告诉您两个文件是否不同,但它们非常有用 如果两个文件相同,它们将具有相同的校验和 因此,如果校验和不同,您绝对知道文件不同 但两个不同的文件有时也可能具有相

我正在开发一个web应用程序(使用JavaEE6和GF3.1),允许用户上传pdf文件。由于这是一个封闭的小社区,上传的文件很可能已经在系统中。我不能只检查名称是否重复,因为这显然是不够的。我在考虑散列整个文件并将条目存储在数据库中。这是否可行,如何实现?如果没有,那么还有什么更好的方法

考虑使用校验和

这是从

编辑

请注意,校验和不能绝对告诉您两个文件是否不同,但它们非常有用

如果两个文件相同,它们将具有相同的校验和

因此,如果校验和不同,您绝对知道文件不同

但两个不同的文件有时也可能具有相同的校验和

所以使用这个的方法是首先计算校验和-如果它们不同,文件也不同。如果它们是相同的,则必须逐字节进行比较。当然,这要慢一些,但不会经常发生


注意所有这些也适用于哈希代码。

考虑使用校验和

这是从

编辑

请注意,校验和不能绝对告诉您两个文件是否不同,但它们非常有用

如果两个文件相同,它们将具有相同的校验和

因此,如果校验和不同,您绝对知道文件不同

但两个不同的文件有时也可能具有相同的校验和

所以使用这个的方法是首先计算校验和-如果它们不同,文件也不同。如果它们是相同的,则必须逐字节进行比较。当然,这要慢一些,但不会经常发生


注意所有这些也适用于哈希代码。

您的解决方案非常优雅。计算文件内容的散列(MD5可能足以启动),并将其用作数据库中的主键。您也可以将文件保存在数据库中,或者保存在外部的某个位置(对此存在很多争议)


下次有人上传文件时,计算散列,检查数据库,如果没有,则保存。

您的解决方案非常优雅。计算文件内容的散列(MD5可能足以启动),并将其用作数据库中的主键。您也可以将文件保存在数据库中,或者保存在外部的某个位置(对此存在很多争议)


下次有人上传文件时,计算散列,检查数据库,如果没有,保存。

是的,这是可行的。事实上,P2P程序就是这样识别文件的

使用任何加密哈希算法(MD5、SHA-1等)

Java支持使用该类进行哈希运算


但是请注意,这样可以避免存储重复的文件,但不会阻止用户上载文件:只有在服务器端,您才能访问文件内容并对其进行散列,除非您使用具有访问本地文件权限的小程序或webstart应用。

是的,这是可行的。事实上,P2P程序就是这样识别文件的

使用任何加密哈希算法(MD5、SHA-1等)

Java支持使用该类进行哈希运算


但是请注意,这样可以避免存储重复的文件,但不会阻止用户上载文件:只有在服务器端,您才能访问文件内容并对其进行散列,除非您使用具有访问本地文件权限的小程序或webstart应用。

当然,这是可行的,您可以使用该类来执行此操作。例如:

InputStream is = // input stream of the uploaded file
byte[] buffer = new byte[1024];
byte[] digest;
try {
    MessageDigest md = MessageDigest.getInstance("MD5");

    for (int count = is.read(buffer); count != -1; count = is.read(buffer)) {
        md.update(buffer, 0, count);
    }

    digest = md.digest();
    // store digest as needed, possibly Base64 encode first
}
catch (NoSuchAlgorithmException e) {
    // handle
}

当然,这是可行的,您可以使用该类来实现这一点。例如:

InputStream is = // input stream of the uploaded file
byte[] buffer = new byte[1024];
byte[] digest;
try {
    MessageDigest md = MessageDigest.getInstance("MD5");

    for (int count = is.read(buffer); count != -1; count = is.read(buffer)) {
        md.update(buffer, 0, count);
    }

    digest = md.digest();
    // store digest as needed, possibly Base64 encode first
}
catch (NoSuchAlgorithmException e) {
    // handle
}

在过去,我使用过Timothy W Macinta(可能是如此的User@Tim Macinta)

最简单的例子是:

// imports: java.io.File and com.twmacinta.util.MD5;

String hash = MD5.asHex(MD5.getHash(new File(filename)));

此实用程序还可以使用本机库来提高性能。

过去,我使用过Timothy W Macinta(可能是SO User@Tim Macinta)

最简单的例子是:

// imports: java.io.File and com.twmacinta.util.MD5;

String hash = MD5.asHex(MD5.getHash(new File(filename)));

此实用程序还可以使用本机库来提高性能。

听起来很合理。文件上传不应该太常见,散列计算只进行一次,并且不是计算密集型的。听起来很合理。文件上载不应该太常见,哈希计算只进行一次,而且计算量也不是很大。+1因为这里不建议使用安全哈希,CRC32更快,安全性不是问题的关键。@Harry-是和否。是的,校验和保证唯一性:如果两个文件产生不同的校验和,这些文件是不同的。但事实并非如此:两个不同的文件可能有不同的校验和(哈希或任何其他导致值小于原始值的特征化方法也是如此)。@emboss-谢谢,我同意这种情况下的速度和安全性需求。@RMT-谢谢您的编辑。遗憾的是,无法对编辑进行升级。@CPerkins:那么两个不同的文件可能具有相同的校验和?这有点糟糕。如果我用SHA-256而不是MD5散列文件,它能保证唯一性吗?+1因为这里不建议使用安全散列,CRC32更快,安全性不是问题的关键。@Harry-是和否。是的,校验和保证唯一性:如果两个文件产生不同的校验和,则文件不同。但事实并非如此:两个不同的文件可能有不同的校验和(哈希或任何其他导致值小于原始值的特征化方法也是如此)。@emboss-谢谢,我同意这种情况下的速度和安全性需求。@RMT-谢谢您的编辑。遗憾的是,无法对编辑进行升级。@CPerkins:那么两个不同的文件可能具有相同的校验和?这有点糟糕。如果我用SHA-256而不是MD5散列文件,它能保证唯一性吗