Android中SHA1哈希实现的问题
||
我有两个用于计算SHA1的小片段。
一个非常快,但似乎不正确,另一个非常慢,但正确。
我认为将“ 0”转换为“ 1”是个问题。
快速版本:
MessageDigest md = MessageDigest.getInstance(\"SHA1\");
FileInputStream fis = new FileInputStream(\"path/to/file.exe\");
ByteArrayInputStream byteArrayInputStream =
new ByteArrayInputStream(fis.toString().getBytes());
DigestInputStream dis = new DigestInputStream(byteArrayInputStream, md);
BufferedInputStream bis = new BufferedInputStream(fis);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int ch;
while ((ch = dis.read()) != -1) {
byteArrayOutputStream.write(ch);
}
byte[] newInput = byteArrayOutputStream.toByteArray();
System.out.println(\"in digest : \" +
byteArray2Hex(dis.getMessageDigest().digest()));
byteArrayOutputStream = new ByteArrayOutputStream();
DigestOutputStream digestOutputStream =
new DigestOutputStream(byteArrayOutputStream, md);
digestOutputStream.write(newInput);
System.out.println(\"out digest: \" +
byteArray2Hex(digestOutputStream.getMessageDigest().digest()));
System.out.println(\"length: \" +
new String(
byteArray2Hex(digestOutputStream.getMessageDigest().digest())).length());
digestOutputStream.close();
byteArrayOutputStream.close();
dis.close();
慢版本:
MessageDigest algorithm = MessageDigest.getInstance(\"SHA1\");
FileInputStream fis = new FileInputStream(\"path/to/file.exe\");
BufferedInputStream bis = new BufferedInputStream(fis);
DigestInputStream dis = new DigestInputStream(bis, algorithm);
// read the file and update the hash calculation
while (dis.read() != -1);
// get the hash value as byte array
byte[] hash = algorithm.digest();
转换方式:
private static String byteArray2Hex(byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format(\"%02x\", b);
}
return formatter.toString();
}
我希望有另一种可能使其运行,因为我需要性能。
没有找到相关结果
已邀请:
4 个回复
宠封钞轰
导航到带有字母D的驱动器。 在NDK的根文件夹中,您可以使用
执行ndk-build文件。应该出现类似“ 7”的错误。 您必须在Android项目中导航才能执行命令。因此,让我们从一个项目开始。 在开始项目之前,搜索哈希算法的C / C ++实现。我从此站点CSHA1中获取了代码。 您应该根据需要编辑源代码。 现在我们可以从JNI开始。 您在Android项目中创建一个名为jni的文件夹。它还包含所有本机源文件和Android.mk(稍后将进一步介绍该文件)。 将下载的(和编辑的)源文件复制到该文件夹中。 我的Java包称为de.dhbw.file.sha1,因此我将源文件命名为类似文件,以便轻松找到它们。 Android.mk:
Java代码: 我将AsyncTask与ProgressDialog一起使用,以向用户提供有关该操作的一些反馈。
本机代码(C ++): 请记住,访问本机代码内部的变量或使用线程的其他方式需要同步,否则您很快会遇到分段错误! 要使用JNI,您必须添加ѭ10。 对于日志记录,请插入以下内容ѭ11。 现在您可以使用
登录。 第一个参数是消息的类型,第二个参数是原因库。 您可以看到我的代码中有一个版本号。这非常有帮助,因为有时apk生成器不使用新的本机库。如果在线版本错误,则可以极大地缩短故障排除时间。 本机代码中的命名约定有点麻烦:
。 始终提供first到arguments,但是应根据应用程序进行区分:
-> JNI调用是一个实例方法
-> JNI调用是静态方法 方法“ 16”的标头:
JDK提供了二进制javah.exe,该文件生成了本机代码的头文件。用法非常简单,只需使用完全合格的类即可调用它:
在我的情况下,我必须额外提供bootclasspath,因为我使用的是Android类:
那将是生成的文件:
您可以更改文件而无需另行通知。但是不要再使用use21ѭ! 类和方法 要获得一个类实例,可以使用
。在这种情况下,“ 23”是类de / dhbw / file / sha1 / SHA1HashFileAsyncTask的完整限定路径。 要找到一个方法,您需要JNIEnv和该类的实例:
第一个参数是类的实例,第二个参数是方法的名称,第三个是方法的签名。 您可以使用JDK给定的二进制javap.exe从获得的签名。只需使用类f的完整限定路径调用它即可
。 您将得到如下结果:
如果找到该方法,则变量不等于0。 调用方法非常简单:
第一个参数是来自“ main”方法的给定jobject,我认为其他方法很清楚。 请记住,尽管本类是私有方法,但您可以从本机代码调用,因为本机代码是其中的一部分! 弦乐 给定的字符串将使用以下代码转换:
另一种方式:
它可以是每个“ 30”变量。 例外情况 可以与JNIEnv一起抛出:
您还可以检查JNIEnv是否也发生了异常:
技术指标 Java本机接口规范 建立/清洁 建立 创建所有文件并将其填充内容后,便可以对其进行构建。 打开cygwin,导航到项目根目录,然后从该目录执行NDK根目录中的ndk-build。 这开始编译,如果成功,您将得到如下输出:
如果有任何错误,您将从编译器获取典型输出。 清洁 打开cygwin,打开您的Android项目并执行命令
。 建立APK 构建本机库后,您可以构建项目。我发现它很干净,使用eclipse功能清理项目是有利的。 调试 Java代码的调试与以前没有什么不同。 C ++代码的调试将在下一次进行。
渐首洽陈染
性能来自按块处理数据。此处的8 kB缓冲区应该足够块状。由于8 kB缓冲区也可用作I / O缓冲区,因此您不必使用ѭ36。
嗜蒂谷尘旱
调用不读取文件的内容。相反,它为您提供了一个(我怀疑)如下所示的字符串:
然后您要继续计算其SHA1哈希值。
及其超类不会覆盖
... 将InputStream的全部内容读取到ѭ42的简单方法是使用Apache Commons I / O帮助器方法ѭ43。
黎喊病