栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Android中SHA1哈希实现的问题

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android中SHA1哈希实现的问题

我使用了JNI加载的高性能c ++实现。
有关更多详细信息,请发表评论。

编辑:
JNI的要求是Android
NDK。对于Windows,还需要cygwin或类似的东西。
如果您决定使用cygwin,我会给您一些指导,说明如何使其与NDK一起使用:

  1. 从cygwin 下载 setup.exe 并执行。
  2. 点击 下一步 ,并选择 从网络安装 确认有 下一步
  3. 接下来的两个步骤将根据需要调整设置,并一如既往地单击“ 下一步”
  4. 选择您的互联网连接,并按照与最后阶段相同的步骤进行操作。
  5. 选择一个下载页面会吸引您的注意,或者仅下载您所在国家/地区的下载页面。没什么可说的了。
  6. 我们需要软件包 makegcc-g ++ 。您可以使用左上角的搜索找到它们,单击“ 跳过 直到显示版本” ,然后选择第一个字段。完成选择后我们一直做的事情。
  7. 您将获得必须解决的依赖关系信息。通常无需自己进行确认。
  8. 开始下载和安装。
  9. 如果需要,您可以创建快捷方式,否则单击特殊的 Finish
  10. 下载该zip文件,然后将NDK解压缩到不包含路径的路径中。
  11. 您可以立即开始cygwin。
  12. 导航到NDK。路径 / cydrive 为您提供所有可用的驱动器,例如
    cd /cygdrive/d
    导航到字母 D 的驱动器。
  13. 在NDK的根文件夹,您可以执行该文件 NDK建造
    ./ndk-build
    。应该出现类似的错误
    Android NDK: Could not find application project directory !

    您必须在Android项目中导航才能执行命令。因此,让我们从一个项目开始。

在我们从项目开始之前,搜索哈希算法的C / C
++实现。我从此站点CSHA1中获取了代码。
您应该根据需要编辑源代码。

现在我们可以从JNI开始。
您在Android项目中创建一个名为 jni 的文件夹。它还包含所有本机源文件和 Android.mk (稍后将进一步介绍该文件)。
将下载的(和编辑的)源文件复制到该文件夹​​中。

我的java包称为 de.dhbw.file.sha1 ,因此我将源文件命名为类似文件,以便轻松找到它们。

Android.mk:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_LDLIBS := -llog# How the lib is called?LOCAL_MODULE    := SHA1Calc# Which is your main SOURCE(!) file?LOCAL_SRC_FILES := de_dhbw_file_sha1_SHA1Calc.cppinclude $(BUILD_SHARED_LIBRARY)

Java代码:
我将 AsyncTaskProgressDialog结合使用, 以向用户提供有关该操作的一些反馈。

package de.dhbw.file.sha1;// TODO: Add importspublic class SHA1HashFileAsyncTask extends AsyncTask<String, Integer, String> {    // [...]    static {        // loads a native library        System.loadLibrary("SHA1Calc");    }    // [...]    // native is the indicator for native written methods    protected native void calcFileSha1(String filePath);    protected native int getProgress();    protected native void unlockMutex();    protected native String getHash();    // [...]}

本机代码(C ++):

请记住,访问本机代码内部的变量或使用线程的其他方式需要同步,否则您很快会遇到分段错误!

要使用JNI,您必须添加

#include <jni.h>

对于日志记录,请插入include

#include <android/log.h>

现在您可以使用登录
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "Version [%s]","19");

第一个参数是消息的类型,第二个参数是原因库。
您可以看到我的代码中有一个版本号。这很有用,因为有时apk生成器不使用新的本机库。如果在线版本错误,则可以极大地缩短故障排除时间。

本机代码中的命名约定有点麻烦:

Java_[package name]_[class name]_[method name]

始终提供first到arguments,但是应根据应用程序进行区分:

  • func(JNIEnv * env, jobject jobj)
    -> JNI调用是一个实例方法
  • func(JNIEnv * env, jclass jclazz)
    -> JNI调用是静态方法

方法的标头

calcFileSha1(...)

JNIEXPORT void JNICALLJava_de_dhbw_file_sha1_SHA1HashFileAsyncTask_calcFileSha1(JNIEnv * env,jobject jobj, jstring file)

JDK提供了二进制 javah.exe ,该文件生成了本机代码的头文件。用法非常简单,只需使用完全合格的类即可调用它:

javah de.dhbw.file.sha1.SHA1HashFileAsyncTask

在我的情况下,我必须额外提供 bootclasspath ,因为我使用的是Android类:

javah -bootclasspath<path_to_the_used_android_api> de.dhbw.file.sha1.SHA1HashFileAsyncTask

那将是生成的文件:

#include <jni.h>#ifndef _Included_de_dhbw_file_sha1_SHA1HashFileAsyncTask#define _Included_de_dhbw_file_sha1_SHA1HashFileAsyncTask#ifdef __cplusplusextern "C" {#endif#undef de_dhbw_file_sha1_SHA1HashFileAsyncTask_ERROR_CODE#define de_dhbw_file_sha1_SHA1HashFileAsyncTask_ERROR_CODE -1L#undef de_dhbw_file_sha1_SHA1HashFileAsyncTask_PROGRESS_CODE#define de_dhbw_file_sha1_SHA1HashFileAsyncTask_PROGRESS_CODE 1LJNIEXPORT void JNICALL Java_de_dhbw_file_sha1_SHA1HashFileAsyncTask_calcFileSha1  (JNIEnv *, jobject, jstring);JNIEXPORT jint JNICALL Java_de_dhbw_file_sha1_SHA1HashFileAsyncTask_getProgress  (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_de_dhbw_file_sha1_SHA1HashFileAsyncTask_unlockMutex  (JNIEnv *, jobject);JNIEXPORT jstring JNICALL Java_de_dhbw_file_sha1_SHA1HashFileAsyncTask_getHash  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif

您可以更改文件而无需另行通知。 但是不要再使用

javah

类和方法
要获取类实例,可以使用

jclass clz =callEnv->FindClass(CALL_CLASS);
。在这种情况下,是
CALL_CLASS
de / dhbw / file /
sha1 / SHA1HashFileAsyncTask
的完整限定路径。

要查找方法,您需要 JNIEnv 和该类的实例:

jmethodID midSet = callEnv->GetMethodID(callClass, "setFileSize", "(J)V");

第一个参数是该类的实例,第二个参数是该方法的名称,第三个是该方法的签名。
您可以从JDK给定的二进制 javap.exe中 获得签名。只需使用fe类的完全限定路径进行调用即可
javap -sde.dhbw.file.sha1.SHA1HashFileAsyncTask

您将得到如下结果:

Compiled from "SHA1HashFileAsyncTask.java"public class de.dhbw.file.sha1.SHA1HashFileAsyncTask extends android.os.AsyncTask<java.lang.String, java.lang.Integer, java.lang.String> {  [...]  static {};    Signature: ()V  public de.dhbw.file.sha1.SHA1HashFileAsyncTask(android.content.Context, de.dhbw.file.sha1.SHA1HashFileAsyncTask$SHA1AsyncTaskListener);    Signature: (Landroid/content/Context;Lde/dhbw/file/sha1/SHA1HashFileAsyncTask$SHA1AsyncTaskListener;)V  protected native void calcFileSha1(java.lang.String);    Signature: (Ljava/lang/String;)V  protected native int getProgress();    Signature: ()I  protected native void unlockMutex();    Signature: ()V  protected native java.lang.String getHash();    Signature: ()Ljava/lang/String;  [...]  public void setFileSize(long);    Signature: (J)V  [...]}

如果找到该方法,则变量不等于0。
调用该方法非常容易:

callEnv->CallVoidMethod(callObj, midSet, size);

第一个参数是“ main”方法给定的 jobject ,我认为其他方法很明确。

请记住,尽管本类是私有方法,但您可以从本机代码调用,因为本机代码是其中的一部分!

字符串
给定的字符串将与下面的代码转换:

jboolean jbol;const char *fileName = env->GetStringUTFChars(file, &jbol);

另一种方式:

TCHAR* szReport = new TCHAR;jstring result = callEnv->NewStringUTF(szReport);

它可以是每个

char*
变量。

例外情况
可与抛出 的JNIEnv

callEnv->ThrowNew(callEnv->FindClass("java/lang/Exception"),     "Hash generation failed");

您还可以检查 JNIEnv 是否也发生了异常:

if (callEnv->ExceptionOccurred()) {    callEnv->ExceptionDescribe();    callEnv->ExceptionClear();}

技术指标

  • Java本机接口规范

建立/清洁

生成
创建完所有文件并将其填充内容之后,就可以对其进行生成。
打开cygwin,导航到项目根目录,然后从NDK根目录中执行 ndk-build
这开始编译,如果成功,您将得到如下输出:

$ /cygdrive/d/android-ndk-r5c/ndk-buildCompile++ thumb  : SHA1Calc <= SHA1Calc.cppSharedLibrary  : libSHA1Calc.soInstall        : libSHA1Calc.so => libs/armeabi/libSHA1Calc.so

如果有任何错误,您将从编译器获取典型输出。

清洁
打开cygwin,打开您的Android项目并执行命令

/cygdrive/d/android-ndk-r5c/ndk-build clean

生成apk
在构建本机库之后,您可以构建您的项目。我发现干净了,使用eclipse功能 清理项目 是有利的。

调试
Java代码的调试与以前没有什么不同。
C ++代码的调试将在下一次进行。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/595582.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号