gpt4 book ai didi

java - Adler32 生成校验和与 .txt 文件校验和不匹配

转载 作者:行者123 更新时间:2023-12-02 08:50:45 25 4
gpt4 key购买 nike

我的任务是编写两个 Java 程序。一个程序创建一个名为“userinput.txt”的文件,然后将用户输入的所有内容写入该文件。完成后,将创建一个名为“Checksum.txt”的新文件,该文件将在读取“userinput.txt”文件内部的内容后记下“userinput.txt”文件的校验和。

第二个程序只是读取相同的“userinput.txt”文件,然后生成一个校验和并将其打印到控制台上(我还必须让程序读取其他 checksum.txt 文件并将其显示在控制台中比较两者,但我还没有时间考虑这一点)。

我为这两个编写了程序,但我的问题是它们的校验和不同,即使它们正在读取相同的文件。我使用 Adler32,但 CRC32 还给了我两个不同的校验和(控制台上的校验和总是与 checksum.txt 中存储的校验和不同),坦白说我不确定是什么导致了它:/

以下是接受用户输入并生成校验和文件的代码:

package attemp2;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import java.util.zip.Adler32;
import java.util.zip.CheckedInputStream;

public class main {
public static void main(String[] args) throws IOException {
System.out.println("All inputs will be recorded into a sigle file. Enter 'x' when done. A checksum File will aslo be created at the end");
FileWriter fw = new FileWriter("d:/input.txt", false); // clears previous entry in file.
while (true) {
Scanner input = new Scanner(System.in); //get user input
String ch = input.nextLine(); //stores user input
System.out.println(ch); //prints out what user just inputed
if (ch.equals("x")) { //stops running if 'x' is entered
break;
}
BufferedWriter writer = new BufferedWriter(new FileWriter("d:/input.txt", true));
writer.write(ch);
writer.newLine(); // Add new line
writer.close();
}
try {
FileReader reader = new FileReader("d:/input.txt");
BufferedReader br = new BufferedReader(reader);
// read line by line String line;
String read = "";
String line;
while ((line = br.readLine()) != null) {
read = read + line;
//prints out text in file currently
System.out.println(line);
}
//checksum.txt generation
byte buffer[] = read.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
CheckedInputStream cis = new CheckedInputStream(bais, new Adler32());
byte readBuffer[] = new byte[buffer.length];
cis.read(readBuffer);
FileOutputStream out = new FileOutputStream("d://checksum.txt");
BufferedWriter wrt = new BufferedWriter(new FileWriter("d:/checksum.txt", false));
wrt.write(Long.toString(cis.getChecksum().getValue()));
wrt.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

}

读取文件并在控制台中生成校验和的代码:

package check;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Scanner;
import java.util.zip.Adler32;

public class CheckSum {

private Adler32 checksum;
private String filepath;
InputStream inputStream;

public CheckSum(String filepath) throws FileNotFoundException{
this.filepath = filepath;
checksum = new Adler32();
inputStream = new FileInputStream(filepath);
}

public long generateChecksum() throws IOException{

int c;

while((c = inputStream.read())!=-1){
checksum.update(c);
}

return checksum.getValue();
}

public void read() throws IOException{
File file = new File(filepath);

BufferedReader br = new BufferedReader(new FileReader(file));

String st;

while ((st = br.readLine()) != null) {
System.out.println(st);
}
}

public static void main(String[] args) throws Exception{

Scanner scanner = new Scanner(System.in);
String filepath = "d:/input.txt";
CheckSum checksum = new CheckSum(filepath);

checksum.read();

System.out.println("For the file: "+filepath);
System.out.println("The checksum generated is: "+checksum.generateChecksum());


}
}

最佳答案

请了解如何使用调试器,请参阅What is a debugger and how can it help me diagnose problems? .

话虽如此,您的代码存在一些问题。首先,您在空数组上计算校验和。当你写:

byte readBuffer[] = new byte[buffer.length];
cis.read(readBuffer);

您正在读取 buffer 数组大小的空数组。您不需要创建新数组。事实上,您应该读取已有的 buffer 数组,因为里面有您的内容。在这种情况下,您只需编写:

cis.read(buffer);

下一个问题是您正在使用读取器和写入器,它们用于文本/字符串文件,但校验和/哈希算法通常在字节级别工作。这可能会导致一些错误,例如编码(ASCII、UTF-8 等)和行终止问题(\n\r\n\r)。

但是,在本例中,您正在使用 readLine()。此方法不会在末尾返回行终止符,请参阅 the documentation of readLine() :

Returns:

A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

因此,您从文件中读取的内容与文件中实际的内容不同。但是您的 CheckSum 类会读取保存文件中的每个字节(正如它应该的那样)。假设您仅输入字符串 "abc"。您的第一个计算将在 3 字节长的数组上运行,其值如下:

[97,98,99]

行终止符被 readLine() 方法忽略,但它仍然存在于文件中。当您使用第二个程序检查校验和时,您正在使用的 InputStream 将看到以下字节:

[97,98,99,10]

(末尾的字节取决于您使用的操作系统)

正如您所看到的,您在不同的字节数组上运行校验和,从而产生不同的校验和值。因此,请确保对相同的字节数组内容(或 InputStream 内容)运行校验和检查,以便在两个应用程序中获得相同的校验和。

关于java - Adler32 生成校验和与 .txt 文件校验和不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60796077/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com