2017-02-17 20 views
1

Я пытаюсь создать хеш MD5 для строки, используя исходный/нетронутый md5.h и md5c.c (файл github source: https://github.com/sinhpn92/encryption-in-C/tree/master/app/src/main/cpp). Но мой результат не прав в любое время. Когда я использую устройство samsung galaxy j для тестирования, мой результат прав. Но когда я использую samsung galaxy s7 для тестирования, мой результат неправильный. Что случилось в моем коде? Есть ли предложение решить эту проблему? Благодарю вашу поддержку.Возвращение неправильного хэша md5 в jni

Это мой проект: https://github.com/sinhpn92/encryption-in-C

Я использую CMake для конфигурации JNI Lib:

cmake_minimum_required(VERSION 3.4.1) 

set(MD5SOURCES 
    src/main/cpp/md5.c) 


add_library(native-lib 
      SHARED 
      src/main/cpp/native-lib.cpp 
       ${MD5SOURCES}) 


find_library(log-lib 
       log) 

target_link_libraries(native-lib 
         ${log-lib}) 

И это родной Пб:

#include <jni.h> 
#include <string> 
#include "md5.h" 

extern "C" 
jstring 
Java_test_sinhpn_md5test_MainActivity_stringFromJNI(JNIEnv *env, jobject /* this */, jstring data) { 
    char *cstr = (char *) (env)->GetStringUTFChars(data, 0); 

    MD5_CTX context = {0}; 
    MD5Init(&context); 
    MD5Update(&context, (unsigned char *) cstr, strlen(cstr)); 
    unsigned char dest[16] = {0}; 
    MD5Final(dest, &context); 
    env->ReleaseStringUTFChars(data, cstr); 

    int i; 
    char destination[32] = {0}; 
    for (i = 0; i < 16; i++) { 
     sprintf(destination, "%s%02x", destination, dest[i]); 
    } 
    return env->NewStringUTF(destination); 
} 

Мой build.gradle:

apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 25 
    buildToolsVersion "25.0.2" 
    defaultConfig { 
     applicationId "test.sinhpn.md5test" 
     minSdkVersion 15 
     targetSdkVersion 25 
     versionCode 1 
     versionName "1.0" 
     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
     externalNativeBuild { 
      cmake { 
       cppFlags "-frtti -fexceptions" 
      } 
     } 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
    externalNativeBuild { 
     cmake { 
      path "CMakeLists.txt" 
     } 
    } 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 
     exclude group: 'com.android.support', module: 'support-annotations' 
    }) 
    compile 'com.android.support:appcompat-v7:25.1.1' 
    testCompile 'junit:junit:4.12' 
} 

Это результат моего теста:

enter image description here

enter image description here

+1

Было бы полезно проверить, что разница в поведении не связана с недостатком вашей сторонней библиотеки MD5. Я предлагаю протестировать эту библиотеку на нескольких байтовых последовательностях, выраженных явно (и численно) в источнике C, чтобы подтвердить, что он дает те же результаты в обеих системах. –

+0

Это выглядит проблематично в коде MD5, который вы отправили: '/ * UINT4 определяет четырехбайтное слово */ typedef unsigned long int UINT4;' Это не будет верно на 64-битной платформе с 64-разрядными значениями 'long' .... –

+0

@John Bollinger: Спасибо, ваш комментарий. Я понимаю, что вы предлагаете мне проверить несколько байтов, а не строку? Правильно? –

ответ

2

я решил мою проблему замены:

typedef unsigned long int UINT4; в md5.c ->typedef uint32_t UINT4;.

Я тестировал снова на двух устройствах, и это нормально работает. На 64-битной машине длинный int (обычно) 64 бита длиной вместо 32

+0

phan sinh спасибо, он работает –

0

двух телефонов используют различные наборы инструкций ARM. Galaxy J использует armeabi-v7a, а S7 использует arm64-v8a.

cmake в соответствии с вашими выше сборками делает файл .so для всех архитектур, и это вызывает проблему из-за 32-битных и 64-битных задач преобразования бросков в собственный код.

Однако в вашем случае есть простое исправление. Вы можете ограничить сборки для abiFilters «armeabi-v7a», «armeabi», в вашей конфигурации по умолчанию, как показано ниже

externalNativeBuild { 
     cmake { 
      cppFlags "-frtti -fexceptions" 
      abiFilters "armeabi-v7a", "armeabi" 
     } 
    } 

это должно работать, потому что arm64v8a имеет обратную совместимость со старой архитектурой v7a.

+1

Разница в архитектуре - это важное замечание, но вы видите какие-либо * актуальные проблемы с преобразованием бросков в собственный код или эта часть спекулятивная? –

+0

@Bharat Kumar Molleti: Спасибо, ваш комментарий. Но это не работает. –

+0

@JohnBollinger см. Комментарий к андре./* UINT4 определяет четырехбайтное слово */typedef unsigned long int UINT4; Это будет неверно на 64-битной платформе с 64-разрядными значениями ..., при этом проблемы, как и выше, желательно соблюдать осторожность при таких преобразованиях и приведениях. –