首页 \ 问答 \ 文件md5散列更改时(对于netty传输)(File md5 hash changes when chunking it (for netty transfer))

文件md5散列更改时(对于netty传输)(File md5 hash changes when chunking it (for netty transfer))

底部的问题

我使用netty将文件传输到另一台服务器。 由于WebSocket协议,我将文件块限制为1024 * 64字节(64KB)。 以下方法是本地示例文件会发生什么情况:

public static void rechunck(File file1, File file2) {

    FileInputStream is = null;
    FileOutputStream os = null;

    try {

        byte[] buf = new byte[1024*64];

        is = new FileInputStream(file1);
        os = new FileOutputStream(file2);

        while(is.read(buf) > 0) {
            os.write(buf);
        }

    } catch (IOException e) {
        Controller.handleException(Thread.currentThread(), e);
    } finally {

        try {

            if(is != null && os != null) {
                is.close();
                os.close();
            }

        } catch (IOException e) {
            Controller.handleException(Thread.currentThread(), e);
        }

    }

}

该文件由InputStream加载到ByteBuffer中,并直接写入OutputStream 。 该过程中文件的内容不能改变。

为了获得文件的md5-hashes ,我编写了以下方法:

public static String checksum(File file) {

    InputStream is = null;

    try {

        is = new FileInputStream(file);
        MessageDigest digest = MessageDigest.getInstance("MD5");
        byte[] buffer = new byte[8192];
        int read = 0;

        while((read = is.read(buffer)) > 0) {
            digest.update(buffer, 0, read);
        }

        return new BigInteger(1, digest.digest()).toString(16);

    } catch(IOException | NoSuchAlgorithmException e) {
        Controller.handleException(Thread.currentThread(), e);
    } finally {

        try {
            is.close();
        } catch(IOException e) {
            Controller.handleException(Thread.currentThread(), e);
        }

    }

    return null;

}

所以:理论上它应该返回相同的散列,不是吗? 问题是它返回两个不同的散列,每次运行都没有区别。文件大小保持不变,内容也是一样。 当我in: file-1out: file-2以及in: file-2out: file-3运行一次方法时, in: file-2out: file-3的哈希值是相同的! 这意味着该方法将每次以相同的方式正确更改文件。

1. 58a4a9fbe349a9e0af172f9cf3e6050a
2. 7b3f343fa1b8c4e1160add4c48322373
3. 7b3f343fa1b8c4e1160add4c48322373

这是一个比较所有缓冲区的小测试,如果它们是相同的。 测试是积极的。 所以没有任何分歧。

File file1 = new File("controller/templates/Example.zip");
File file2 = new File("controller/templates2/Example.zip");

try {

    byte[] buf1 = new byte[1024*64];
    byte[] buf2 = new byte[1024*64];

    FileInputStream is1 = new FileInputStream(file1);
    FileInputStream is2 = new FileInputStream(file2);

    boolean run = true;
    while(run) {

        int read1 = is1.read(buf1), read2 = is2.read(buf2);
        String result1 = Arrays.toString(buf1), result2 = Arrays.toString(buf2);
        boolean test = result1.equals(result2);

        System.out.println("1: " + result1);
        System.out.println("2: " + result2);
        System.out.println("--- TEST RESULT: " + test + " ----------------------------------------------------");

        if(!(read1 > 0 && read2 > 0) || !test) run = false;

    }

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

问题: 你能帮我在不更改散列的情况下分块文件吗?


Question at the bottom

I'm using netty to transfer a file to another server. I limit my file-chunks to 1024*64 bytes (64KB) because of the WebSocket protocol. The following method is a local example what will happen to the file:

public static void rechunck(File file1, File file2) {

    FileInputStream is = null;
    FileOutputStream os = null;

    try {

        byte[] buf = new byte[1024*64];

        is = new FileInputStream(file1);
        os = new FileOutputStream(file2);

        while(is.read(buf) > 0) {
            os.write(buf);
        }

    } catch (IOException e) {
        Controller.handleException(Thread.currentThread(), e);
    } finally {

        try {

            if(is != null && os != null) {
                is.close();
                os.close();
            }

        } catch (IOException e) {
            Controller.handleException(Thread.currentThread(), e);
        }

    }

}

The file is loaded by the InputStream into a ByteBuffer and directly written to the OutputStream. The content of the file cannot change while this process.

To get the md5-hashes of the file I've wrote the following method:

public static String checksum(File file) {

    InputStream is = null;

    try {

        is = new FileInputStream(file);
        MessageDigest digest = MessageDigest.getInstance("MD5");
        byte[] buffer = new byte[8192];
        int read = 0;

        while((read = is.read(buffer)) > 0) {
            digest.update(buffer, 0, read);
        }

        return new BigInteger(1, digest.digest()).toString(16);

    } catch(IOException | NoSuchAlgorithmException e) {
        Controller.handleException(Thread.currentThread(), e);
    } finally {

        try {
            is.close();
        } catch(IOException e) {
            Controller.handleException(Thread.currentThread(), e);
        }

    }

    return null;

}

So: just in theory it should return the same hash, shouldn't it? The problem is that it returns two different hashes that do not differ with every run.. file size stays the same and the content either. When I run the method once for in: file-1, out: file-2 and again with in: file-2 and out: file-3 the hashes of file-2 and file-3 are the same! This means the method will properly change the file every time the same way.

1. 58a4a9fbe349a9e0af172f9cf3e6050a
2. 7b3f343fa1b8c4e1160add4c48322373
3. 7b3f343fa1b8c4e1160add4c48322373

Here is a little test that compares all buffers if they are equivalent. Test is positive. So there aren't any differences.

File file1 = new File("controller/templates/Example.zip");
File file2 = new File("controller/templates2/Example.zip");

try {

    byte[] buf1 = new byte[1024*64];
    byte[] buf2 = new byte[1024*64];

    FileInputStream is1 = new FileInputStream(file1);
    FileInputStream is2 = new FileInputStream(file2);

    boolean run = true;
    while(run) {

        int read1 = is1.read(buf1), read2 = is2.read(buf2);
        String result1 = Arrays.toString(buf1), result2 = Arrays.toString(buf2);
        boolean test = result1.equals(result2);

        System.out.println("1: " + result1);
        System.out.println("2: " + result2);
        System.out.println("--- TEST RESULT: " + test + " ----------------------------------------------------");

        if(!(read1 > 0 && read2 > 0) || !test) run = false;

    }

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

Question: Can you help me chunking the file without changing the hash?


原文:https://stackoverflow.com/questions/49588868
更新时间:2022-10-18 07:10

相关问答

更多
  • 你这个打印的是error级别的,你把error换成debug再试试
  • 这是正确的,最初ResultSet的游标指向第一行之前,如果第一个调用next()返回false则ResultSet没有数据。 如果您使用此方法,则可能必须立即调用beforeFirst()来重置它,因为它已经将自己定位在第一行之后。 然而,应该注意的是, Seifer的答案是对这个问题的更为优雅的解决方案。 That's correct, initially the ResultSet's cursor is pointing to before the first row, if the first c ...
  • coldfusion.sql.QueryTable实现了javax.sql.RowSet,它扩展了java.sql.ResultSet 因此,正如你发现的那样,你不需要做任何事情。 ColdFusion查询已经是Java ResultSet。 coldfusion.sql.QueryTable implements javax.sql.RowSet, which extends java.sql.ResultSet Thus, as you discovered, you don't need to do ...
  • 基本上您将光标定位在第一行之前,然后请求数据。 您需要将光标移动到第一行。 result.next(); String foundType = result.getString(1); 在if语句或循环中这样做是很常见的。 if(result.next()){ foundType = result.getString(1); } Basically you are positioning the cursor before the first row and then requesting d ...
  • java.sql.Timestamp扩展java.util.Date 。 你想要这样的东西: String S = new SimpleDateFormat("MM/dd/yyyy").format(myTimestamp); 包括时间: String S = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(myTimestamp); java.sql.Timestamp extends java.util.Date. You can do: Str ...
  • DarkSquirrel42是对的 - 您无法使用?替换select列列表? 参数标记。 相反,您也可以将String.format格式化为例如。 坏: *select ? from INVENTORY_TABLE_NAME where SKU = ? 好: select QUANTITY_IN_STOCK from INVENTORY_TABLE_NAME where SKU = ? DarkSquirrel42 is right -- you can't replace the column lis ...
  • 你不应该重用一个Statement。 创建新查询时,需要使用新的Statement对象。 替换rs1 = stmt.executeQuery("SELECT ASK FROM '" + title + "' ;"); rs1=c.createStatement().executeQuery("SELECT ASK FROM '" + title + "' ;"); you should not reuse a Statement. When you create a new Query, you need ...
  • 你需要自己处理ResultSet对象rs 。 while(rs.next()){ String ign = rs.getString("IGN"); // ... get uuid and admin level System.out.println(ign + uuid ...); } 如果您不知道列名称,请使用ResultSet#getMetaData() : ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd ...
  • 不是真的。 使用Groovy的Sql主要原因之一是自动处理资源(这就是为什么有些方法使用闭包与ResultSet进行交互,但是没有返回它的方法 - 以确保它们被关闭)。 我强烈建议您重新考虑为什么要传递对ResultSet引用(可以保留服务器资源),而不是使用表示这些结果的POJO / POGO。 但是,如果您坚持使用ResultSet ,并且只需要很少的便捷方法,我想一个选项就是将这些方法复制到您的代码库中。 正如您从源代码中看到的那样, Sql是一个比普通旧JDBC更薄的包装器。 但是,就你所听到的情况 ...
  • 据我所知,ResultSet不“包含”数据。 如果您调用http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#next(),ResultSet将从与数据库的基础(JDBC)连接获取数据。 如果ResultSet是序列化并传输到另一台计算机,则这是不可能的。 那里的连接将无法使用。 As far as I know the ResultSet does not "contain" the data. If you call http: ...

相关文章

更多

最新问答

更多
  • 如何在Laravel 5.2中使用paginate与关系?(How to use paginate with relationships in Laravel 5.2?)
  • linux的常用命令干什么用的
  • 由于有四个新控制器,Auth刀片是否有任何变化?(Are there any changes in Auth blades due to four new controllers?)
  • 如何交换返回集中的行?(How to swap rows in a return set?)
  • 在ios 7中的UITableView部分周围绘制边界线(draw borderline around UITableView section in ios 7)
  • 使用Boost.Spirit Qi和Lex时的空白队长(Whitespace skipper when using Boost.Spirit Qi and Lex)
  • Java中的不可变类(Immutable class in Java)
  • WordPress发布查询(WordPress post query)
  • 如何在关系数据库中存储与IPv6兼容的地址(How to store IPv6-compatible address in a relational database)
  • 是否可以检查对象值的条件并返回密钥?(Is it possible to check the condition of a value of an object and JUST return the key?)
  • GEP分段错误LLVM C ++ API(GEP segmentation fault LLVM C++ API)
  • 绑定属性设置器未被调用(Bound Property Setter not getting Called)
  • linux ubuntu14.04版没有那个文件或目录
  • 如何使用JSF EL表达式在param中迭代变量(How to iterate over variable in param using JSF EL expression)
  • 是否有可能在WPF中的一个单独的进程中隔离一些控件?(Is it possible to isolate some controls in a separate process in WPF?)
  • 使用Python 2.7的MSI安装的默认安装目录是什么?(What is the default installation directory with an MSI install of Python 2.7?)
  • 寻求多次出现的表达式(Seeking for more than one occurrence of an expression)
  • ckeditor config.protectedSource不适用于editor.insertHtml上的html元素属性(ckeditor config.protectedSource dont work for html element attributes on editor.insertHtml)
  • linux只知道文件名,不知道在哪个目录,怎么找到文件所在目录
  • Actionscript:检查字符串是否包含域或子域(Actionscript: check if string contains domain or subdomain)
  • 将CouchDB与AJAX一起使用是否安全?(Is it safe to use CouchDB with AJAX?)
  • 懒惰地初始化AutoMapper(Lazily initializing AutoMapper)
  • 使用hasclass为多个div与一个按钮问题(using hasclass for multiple divs with one button Problems)
  • Windows Phone 7:检查资源是否存在(Windows Phone 7: Check If Resource Exists)
  • 无法在新线程中从FREContext调用getActivity()?(Can't call getActivity() from FREContext in a new thread?)
  • 在Alpine上升级到postgres96(/ usr / bin / pg_dump:没有这样的文件或目录)(Upgrade to postgres96 on Alpine (/usr/bin/pg_dump: No such file or directory))
  • 如何按部门显示报告(How to display a report by Department wise)
  • Facebook墙贴在需要访问令牌密钥后无法正常工作(Facebook wall post not working after access token key required)
  • Javascript - 如何在不擦除输入的情况下更改标签的innerText(Javascript - how to change innerText of label while not wiping out the input)
  • WooCommerce / WordPress - 不显示具有特定标题的产品(WooCommerce/WordPress - Products with specific titles are not displayed)