@ -1,35 +1,15 @@ |
||||
# ---> Android |
||||
# Gradle files |
||||
.gradle/ |
||||
build/ |
||||
|
||||
# Local configuration file (sdk path, etc) |
||||
local.properties |
||||
|
||||
# Log/OS Files |
||||
*.log |
||||
|
||||
# Android Studio generated files and folders |
||||
captures/ |
||||
.externalNativeBuild/ |
||||
.cxx/ |
||||
*.apk |
||||
output.json |
||||
|
||||
# IntelliJ |
||||
*.iml |
||||
.idea/ |
||||
misc.xml |
||||
deploymentTargetDropDown.xml |
||||
render.experimental.xml |
||||
|
||||
# Keystore files |
||||
*.jks |
||||
*.keystore |
||||
|
||||
# Google Services (e.g. APIs or Firebase) |
||||
google-services.json |
||||
|
||||
# Android Profiling |
||||
*.hprof |
||||
|
||||
.gradle |
||||
/local.properties |
||||
/.idea/caches |
||||
/.idea/libraries |
||||
/.idea/modules.xml |
||||
/.idea/workspace.xml |
||||
/.idea/navEditor.xml |
||||
/.idea/assetWizardSettings.xml |
||||
.DS_Store |
||||
/build |
||||
/captures |
||||
.externalNativeBuild |
||||
.cxx |
||||
local.properties |
||||
|
@ -0,0 +1 @@ |
||||
/build |
@ -0,0 +1,43 @@ |
||||
plugins { |
||||
id 'com.android.application' |
||||
} |
||||
|
||||
android { |
||||
namespace 'cn.org.landcloud.survey' |
||||
compileSdk 32 |
||||
|
||||
defaultConfig { |
||||
applicationId "cn.org.landcloud.survey" |
||||
minSdk 21 |
||||
targetSdk 32 |
||||
versionCode 1 |
||||
versionName "1.0" |
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" |
||||
} |
||||
|
||||
buildTypes { |
||||
release { |
||||
minifyEnabled false |
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' |
||||
} |
||||
} |
||||
compileOptions { |
||||
sourceCompatibility JavaVersion.VERSION_1_8 |
||||
targetCompatibility JavaVersion.VERSION_1_8 |
||||
} |
||||
} |
||||
|
||||
dependencies { |
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1' |
||||
implementation 'com.google.android.material:material:1.6.1' |
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' |
||||
implementation project(path: ':ssl') |
||||
testImplementation 'junit:junit:4.13.2' |
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3' |
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' |
||||
implementation "androidx.room:room-runtime:2.2.6" |
||||
annotationProcessor "androidx.room:room-compiler:2.2.6" |
||||
|
||||
} |
@ -0,0 +1,21 @@ |
||||
# Add project specific ProGuard rules here. |
||||
# You can control the set of applied configuration files using the |
||||
# proguardFiles setting in build.gradle. |
||||
# |
||||
# For more details, see |
||||
# http://developer.android.com/guide/developing/tools/proguard.html |
||||
|
||||
# If your project uses WebView with JS, uncomment the following |
||||
# and specify the fully qualified class name to the JavaScript interface |
||||
# class: |
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { |
||||
# public *; |
||||
#} |
||||
|
||||
# Uncomment this to preserve the line number information for |
||||
# debugging stack traces. |
||||
#-keepattributes SourceFile,LineNumberTable |
||||
|
||||
# If you keep the line number information, uncomment this to |
||||
# hide the original source file name. |
||||
#-renamesourcefileattribute SourceFile |
@ -0,0 +1,26 @@ |
||||
package cn.org.landcloud.survey; |
||||
|
||||
import android.content.Context; |
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry; |
||||
import androidx.test.ext.junit.runners.AndroidJUnit4; |
||||
|
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
|
||||
import static org.junit.Assert.*; |
||||
|
||||
/** |
||||
* Instrumented test, which will execute on an Android device. |
||||
* |
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a> |
||||
*/ |
||||
@RunWith(AndroidJUnit4.class) |
||||
public class ExampleInstrumentedTest { |
||||
@Test |
||||
public void useAppContext() { |
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); |
||||
assertEquals("cn.org.landcloud.survey", appContext.getPackageName()); |
||||
} |
||||
} |
@ -0,0 +1,35 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools"> |
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> |
||||
<uses-permission android:name="android.permission.INTERNET"/> |
||||
|
||||
<application |
||||
android:allowBackup="true" |
||||
android:dataExtractionRules="@xml/data_extraction_rules" |
||||
android:fullBackupContent="@xml/backup_rules" |
||||
android:icon="@mipmap/ic_launcher" |
||||
android:label="@string/app_name" |
||||
android:roundIcon="@mipmap/ic_launcher_round" |
||||
android:supportsRtl="true" |
||||
android:usesCleartextTraffic="true" |
||||
android:requestLegacyExternalStorage="true" |
||||
android:theme="@style/Theme.Landsurvey" |
||||
tools:targetApi="31"> |
||||
<activity |
||||
android:name=".MainActivity" |
||||
android:exported="true"> |
||||
<intent-filter> |
||||
<action android:name="android.intent.action.MAIN" /> |
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" /> |
||||
</intent-filter> |
||||
|
||||
<meta-data |
||||
android:name="android.app.lib_name" |
||||
android:value="" /> |
||||
</activity> |
||||
</application> |
||||
|
||||
</manifest> |
After Width: | Height: | Size: 291 KiB |
After Width: | Height: | Size: 634 KiB |
After Width: | Height: | Size: 676 KiB |
After Width: | Height: | Size: 2.4 MiB |
@ -0,0 +1,156 @@ |
||||
package cn.org.landcloud.survey; |
||||
|
||||
import static cn.org.landcloud.survey.data.DataRepositories.RELATIVE_FJ_DIR; |
||||
import static cn.org.landcloud.survey.data.DataRepositories.RELATIVE_PATH; |
||||
|
||||
import android.Manifest; |
||||
import android.app.AlertDialog; |
||||
import android.content.DialogInterface; |
||||
import android.content.pm.PackageManager; |
||||
import android.os.Bundle; |
||||
import android.os.Environment; |
||||
import android.view.View; |
||||
import android.widget.TextView; |
||||
|
||||
import androidx.appcompat.app.AppCompatActivity; |
||||
import androidx.core.app.ActivityCompat; |
||||
import androidx.core.content.ContextCompat; |
||||
|
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.nio.charset.StandardCharsets; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
import cn.org.landcloud.security.sm2.SM2EncDecUtils; |
||||
import cn.org.landcloud.security.sm2.SM2KeyVO; |
||||
import cn.org.landcloud.security.sm2.SM2SignVO; |
||||
import cn.org.landcloud.security.sm2.SM2SignVerUtils; |
||||
import cn.org.landcloud.security.sm3.SM3Utils; |
||||
import cn.org.landcloud.survey.data.DataRepositories; |
||||
import cn.org.landcloud.survey.data.LandSurveyDatabase; |
||||
import cn.org.landcloud.survey.util.Constants; |
||||
import cn.org.landcloud.survey.util.FileIOUtils; |
||||
import cn.org.landcloud.survey.util.Utils; |
||||
|
||||
public class MainActivity extends AppCompatActivity { |
||||
|
||||
private static final int REQUEST_CODE = 0x1000; |
||||
|
||||
private TextView logView; |
||||
|
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
setContentView(R.layout.activity_main); |
||||
initView(); |
||||
checkPermissions(); |
||||
} |
||||
|
||||
|
||||
private void checkPermissions() { |
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { |
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { |
||||
// 申请权限
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); |
||||
} else { |
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
private void initView() { |
||||
logView = findViewById(R.id.log_tv); |
||||
} |
||||
|
||||
@Override |
||||
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { |
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults); |
||||
switch (requestCode) { |
||||
case REQUEST_CODE: { |
||||
if (grantResults.length > 0) { |
||||
for (int grantresult : grantResults) { |
||||
if (grantresult != PackageManager.PERMISSION_GRANTED) { |
||||
new AlertDialog.Builder(MainActivity.this).setTitle("系统提示") |
||||
.setMessage("有部分权限授权失败,请通过后台应用设置重新授权!") |
||||
.setPositiveButton("确定", new DialogInterface.OnClickListener() { |
||||
@Override |
||||
public void onClick(DialogInterface dialog, int which) {//确定按钮的响应事件
|
||||
finish(); |
||||
} |
||||
}).show(); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected void onDestroy() { |
||||
super.onDestroy(); |
||||
logView.setText(""); |
||||
} |
||||
|
||||
/** |
||||
* @param view |
||||
*/ |
||||
public void createSSL(View view) { |
||||
SM2KeyVO result = SM2EncDecUtils.generateKeyPair(); |
||||
logView.append("--产生SM2密钥--:\n"); |
||||
logView.append("公钥:" + result.getPubHexInSoft() + "\n"); |
||||
logView.append("私钥:" + result.getPriHexInSoft() + "\n"); |
||||
} |
||||
|
||||
/** |
||||
* @param view |
||||
*/ |
||||
public void initData(View view) { |
||||
logView.append("--开始生成样例成果db包--:\n"); |
||||
DataRepositories.getInstance().initData(this); |
||||
File file = new File(Environment.getExternalStorageDirectory(), RELATIVE_PATH); |
||||
LandSurveyDatabase.getInstance().destroy(); |
||||
logView.append("--样例成果db包生成完成,路径为--:" + file.getPath() + "\n"); |
||||
} |
||||
|
||||
/** |
||||
* @param view |
||||
*/ |
||||
public void getJYM(View view) { |
||||
logView.append("--开始生成附件信息签名--:\n"); |
||||
|
||||
File file = new File(Environment.getExternalStorageDirectory(),RELATIVE_FJ_DIR+"phone_1.jpg"); |
||||
StringBuffer stringBuffer = new StringBuffer(); |
||||
try { |
||||
String fjhxz = SM3Utils.sm3(file); |
||||
stringBuffer.append(fjhxz).append(","); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
// FJHXZ,PSSJ,Longitude,Latitude,PSFYJ,PSJD,PSHGJ,PSRY,ZSDM
|
||||
stringBuffer.append("2022-10-18 15:42:56,119.98547,30.277615,41.0,239.0,2.0,test,1001"); |
||||
String jym = Utils.makeJYM(stringBuffer.toString(),Constants.TEST_PRIVATEKEY); |
||||
logView.append("--附件信息签名--:" + jym + "\n"); |
||||
} |
||||
|
||||
/** |
||||
* @param view |
||||
*/ |
||||
public void getHash(View view) { |
||||
logView.append("--开始生成图片Hash--:\n"); |
||||
File file = new File(Environment.getExternalStorageDirectory(), RELATIVE_FJ_DIR+"phone_1.jpg"); |
||||
if (!file.isFile() || !file.exists()) { |
||||
logView.append("没有找到文件:" + file.getPath() + "\n"); |
||||
return; |
||||
} |
||||
try { |
||||
String hashCode = SM3Utils.sm3(file); |
||||
logView.append("--Hash值--:" + hashCode + "\n"); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
logView.append("--生成Hash值失败--:" + e.getMessage() + "\n"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,54 @@ |
||||
package cn.org.landcloud.survey.data; |
||||
|
||||
|
||||
import androidx.room.Dao; |
||||
import androidx.room.Delete; |
||||
import androidx.room.Insert; |
||||
import androidx.room.OnConflictStrategy; |
||||
import androidx.room.Update; |
||||
|
||||
import java.util.List; |
||||
|
||||
import cn.org.landcloud.survey.data.bean.DBInfo; |
||||
import cn.org.landcloud.survey.data.bean.FJ; |
||||
|
||||
|
||||
@Dao |
||||
public interface DBInfoDao { |
||||
|
||||
|
||||
/** |
||||
* 插入一条新的附件 |
||||
* 如插入时发生冲突,处理方式为插入一个新的对象。 |
||||
* |
||||
* @param dbInfo |
||||
* @return |
||||
*/ |
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
long insertDBInfo(DBInfo dbInfo); |
||||
|
||||
@Update |
||||
int updateDBInfo(DBInfo dbInfo); |
||||
|
||||
@Delete |
||||
int deleteDBInfo(DBInfo dbInfo); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertDBInfo(DBInfo... dbInfo); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertDBInfo(List<DBInfo> dbInfos); |
||||
|
||||
@Update |
||||
void updateDBInfo(DBInfo... dbInfo); |
||||
|
||||
@Update |
||||
void updateDBInfo(List<DBInfo> dbInfo); |
||||
|
||||
@Delete |
||||
void deleteDBInfo(DBInfo... dbInfo); |
||||
|
||||
@Delete |
||||
void deleteDBInfo(List<DBInfo> dbInfo); |
||||
|
||||
} |
@ -0,0 +1,53 @@ |
||||
package cn.org.landcloud.survey.data; |
||||
|
||||
|
||||
import androidx.room.Dao; |
||||
import androidx.room.Delete; |
||||
import androidx.room.Insert; |
||||
import androidx.room.OnConflictStrategy; |
||||
import androidx.room.Update; |
||||
|
||||
import java.util.List; |
||||
|
||||
import cn.org.landcloud.survey.data.bean.DCHSXX; |
||||
|
||||
|
||||
@Dao |
||||
public interface DCHSXXDao { |
||||
|
||||
|
||||
/** |
||||
* 插入一条新的附件 |
||||
* 如插入时发生冲突,处理方式为插入一个新的对象。 |
||||
* |
||||
* @param dchsxx |
||||
* @return |
||||
*/ |
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
long insertDCHSXX(DCHSXX dchsxx); |
||||
|
||||
@Update |
||||
int updateDCHSXX(DCHSXX dchsxx); |
||||
|
||||
@Delete |
||||
int deleteDCHSXX(DCHSXX dchsxx); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertDCHSXX(DCHSXX... dchsxx); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertDCHSXX(List<DCHSXX> dchsxxs); |
||||
|
||||
@Update |
||||
void updateDCHSXX(DCHSXX... dchsxx); |
||||
|
||||
@Update |
||||
void updateDCHSXX(List<DCHSXX> dchsxx); |
||||
|
||||
@Delete |
||||
void deleteDCHSXX(DCHSXX... dchsxx); |
||||
|
||||
@Delete |
||||
void deleteDCHSXX(List<DCHSXX> fj); |
||||
|
||||
} |
@ -0,0 +1,476 @@ |
||||
package cn.org.landcloud.survey.data; |
||||
|
||||
import static cn.org.landcloud.survey.util.Constants.CERT_ORG_CODE; |
||||
import static cn.org.landcloud.survey.util.Constants.TEST_CER; |
||||
import static cn.org.landcloud.survey.util.Constants.TEST_CERT_ORG_PUBLICKEY; |
||||
import static cn.org.landcloud.survey.util.Constants.TEST_PUBLICKEY; |
||||
|
||||
import android.content.Context; |
||||
import android.os.Environment; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
|
||||
import org.json.JSONObject; |
||||
|
||||
import java.io.File; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.HashMap; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
import cn.org.landcloud.security.sm2.SM2SignVO; |
||||
import cn.org.landcloud.security.sm2.SM2SignVerUtils; |
||||
import cn.org.landcloud.security.sm3.SM3Utils; |
||||
import cn.org.landcloud.survey.util.Constants; |
||||
import cn.org.landcloud.survey.util.FileIOUtils; |
||||
import cn.org.landcloud.survey.util.TimeUtils; |
||||
import cn.org.landcloud.survey.util.Utils; |
||||
import cn.org.landcloud.survey.data.bean.DBInfo; |
||||
import cn.org.landcloud.survey.data.bean.DCHSXX; |
||||
import cn.org.landcloud.survey.data.bean.FJ; |
||||
import cn.org.landcloud.survey.data.bean.JMXX; |
||||
import cn.org.landcloud.survey.data.bean.KZXXYSJ; |
||||
import cn.org.landcloud.survey.data.bean.TBJBXX; |
||||
|
||||
public class DataRepositories { |
||||
|
||||
private static DataRepositories instance; |
||||
|
||||
public static final String DB_NAME = "landcloud_demo.db"; |
||||
public static final String FJ_NAME_1 = "phone_1.jpg"; |
||||
public static final String FJ_NAME_2 = "phone_panoramic_1.jpg"; |
||||
public static final String FJ_NAME_3 = "phone_video_1.mp4"; |
||||
public static final String FJ_NAME_4 = "photo_uav_1658133414992.jpg"; |
||||
public static final String FJ_NAME_5 = "photo_uav_1658133423647_panoramic.jpg"; |
||||
public static final String RELATIVE_PATH = "testData/"+DB_NAME; |
||||
public static final String RELATIVE_FJ_DIR = "testData/fj/"; |
||||
|
||||
private DataRepositories() { |
||||
|
||||
} |
||||
|
||||
public static DataRepositories getInstance() { |
||||
if (instance == null) { |
||||
synchronized (DataRepositories.class) { |
||||
instance = new DataRepositories(); |
||||
} |
||||
} |
||||
return instance; |
||||
} |
||||
|
||||
public void initData(@NonNull Context context) { |
||||
initDb(context); |
||||
File file = new File(Environment.getExternalStorageDirectory(),RELATIVE_PATH); |
||||
LandSurveyDatabase.init(context,file.getPath()); |
||||
// LandSurveyDatabase.getInstance().clearAllTables();
|
||||
initTestData(context); |
||||
} |
||||
|
||||
private void initTestData(@NonNull Context context) { |
||||
//测试扩展信息
|
||||
KZXXYSJ jbxx_dlbm = new KZXXYSJ(); |
||||
jbxx_dlbm.setBSM(1); |
||||
jbxx_dlbm.setTBLX("JCTB"); |
||||
jbxx_dlbm.setZDMC("DLBM"); |
||||
jbxx_dlbm.setZDBM("地类编码"); |
||||
jbxx_dlbm.setZDMS("地类编码"); |
||||
jbxx_dlbm.setZDLX("TEXT"); |
||||
jbxx_dlbm.setZDCD(20); |
||||
jbxx_dlbm.setSFBT("M"); |
||||
jbxx_dlbm.setKZXXLX("JBXX"); |
||||
|
||||
KZXXYSJ jbxx_dlmc = new KZXXYSJ(); |
||||
jbxx_dlmc.setBSM(2); |
||||
jbxx_dlmc.setTBLX("JCTB"); |
||||
jbxx_dlmc.setZDMC("DLMC"); |
||||
jbxx_dlmc.setZDBM("地类名称"); |
||||
jbxx_dlmc.setZDMS("地类名称"); |
||||
jbxx_dlmc.setZDLX("TEXT"); |
||||
jbxx_dlmc.setZDCD(20); |
||||
jbxx_dlmc.setSFBT("O"); |
||||
jbxx_dlmc.setKZXXLX("JBXX"); |
||||
|
||||
KZXXYSJ dcxx_bglx = new KZXXYSJ(); |
||||
dcxx_bglx.setBSM(3); |
||||
dcxx_bglx.setTBLX("JCTB"); |
||||
dcxx_bglx.setZDMC("BGLX"); |
||||
dcxx_bglx.setZDBM("变更类型"); |
||||
dcxx_bglx.setZDMS("变更类型"); |
||||
dcxx_bglx.setZDLX("TEXT"); |
||||
dcxx_bglx.setZDCD(20); |
||||
dcxx_bglx.setSFBT("O"); |
||||
dcxx_bglx.setKZXXLX("DCXX"); |
||||
|
||||
KZXXYSJ dcxx_bgfw = new KZXXYSJ(); |
||||
dcxx_bgfw.setBSM(4); |
||||
dcxx_bgfw.setTBLX("JCTB"); |
||||
dcxx_bgfw.setZDMC("BGFW"); |
||||
dcxx_bgfw.setZDBM("变更范围"); |
||||
dcxx_bgfw.setZDMS("变更范围"); |
||||
dcxx_bgfw.setZDLX("TEXT"); |
||||
dcxx_bgfw.setZDCD(20); |
||||
dcxx_bgfw.setSFBT("O"); |
||||
dcxx_bgfw.setKZXXLX("DCXX"); |
||||
|
||||
LandSurveyDatabase.getInstance().kzxxysjDao().insertKZXXYSJ(jbxx_dlbm,jbxx_dlmc,dcxx_bglx,dcxx_bgfw); |
||||
//测试地块信息
|
||||
TBJBXX tbjbxx = new TBJBXX(); |
||||
tbjbxx.setBSM("8fd575622ffd45ff8ae9fba0b9c5ec20"); |
||||
tbjbxx.setTBLX("JCTB"); |
||||
tbjbxx.setXZQDM("110101"); |
||||
tbjbxx.setXMC("余杭"); |
||||
tbjbxx.setTBBH("CS110101201600000100099"); |
||||
tbjbxx.setTBMC("1"); |
||||
tbjbxx.setTBMJ(9.43); |
||||
tbjbxx.setXZB(40498699.025); |
||||
tbjbxx.setYZB(3350604.784); |
||||
tbjbxx.setBZ(""); |
||||
|
||||
HashMap<String,Object> jbxxMap = new HashMap<>(); |
||||
jbxxMap.put("DLBM","03B2"); |
||||
jbxxMap.put("DLMC","工地草被"); |
||||
JSONObject jbxxKZXXJSON = new JSONObject(jbxxMap); |
||||
tbjbxx.setKZXX(jbxxKZXXJSON.toString()); |
||||
|
||||
tbjbxx.setTBFW("MULTIPOLYGON (((40498699.02535 3350604.7848, 40498697.04095 3350528.7169499993, 40498781.7078 3350530.70135, 40498780.3849 3350606.1077500004, 40498699.02535 3350604.7848)))"); |
||||
|
||||
LandSurveyDatabase.getInstance().tbjbxxDao().insertTBJBXX(tbjbxx); |
||||
//测试调查信息
|
||||
DCHSXX dchsxx = new DCHSXX(); |
||||
dchsxx.setDCRY("张三"); |
||||
dchsxx.setDCSJ("2022-10-14 10:12:13"); |
||||
HashMap<String,Object> dcxxMap = new HashMap<>(); |
||||
dcxxMap.put("BGFW","部分变更"); |
||||
dcxxMap.put("BGLX","0"); |
||||
JSONObject dcxxKZXXJson = new JSONObject(dcxxMap); |
||||
dchsxx.setKZXX(dcxxKZXXJson.toString()); |
||||
dchsxx.setWYHSQK("违法建筑"); |
||||
dchsxx.setTBBSM("8fd575622ffd45ff8ae9fba0b9c5ec20"); |
||||
LandSurveyDatabase.getInstance().dchsxxDao().insertDCHSXX(dchsxx); |
||||
|
||||
DBInfo dbInfo = new DBInfo(); |
||||
dbInfo.setCreatetime(TimeUtils.getNowString()); |
||||
dbInfo.setUpdatetime(TimeUtils.getNowString()); |
||||
dbInfo.setDescription("测试数据包"); |
||||
dbInfo.setCreateuser("admin"); |
||||
dbInfo.setVersion("1.0"); |
||||
LandSurveyDatabase.getInstance().dbInfoDao().insertDBInfo(dbInfo); |
||||
|
||||
JMXX jmxx = new JMXX(); |
||||
jmxx.setZSDM("1001"); |
||||
jmxx.setSZZS(TEST_CER); |
||||
jmxx.setZSBFJGDM(CERT_ORG_CODE); |
||||
jmxx.setZSBFJGGY(TEST_CERT_ORG_PUBLICKEY); |
||||
|
||||
LandSurveyDatabase.getInstance().jmxxDao().insertJMXX(jmxx); |
||||
//测试附件
|
||||
FJ fj_phone_normal = new FJ(); |
||||
|
||||
fj_phone_normal.setBSM("1"); |
||||
fj_phone_normal.setTBLX("JCTB"); |
||||
fj_phone_normal.setTBBSM("8fd575622ffd45ff8ae9fba0b9c5ec20"); |
||||
fj_phone_normal.setXZQDM("110101"); |
||||
fj_phone_normal.setFJMC("110101"); |
||||
fj_phone_normal.setFJLX("0"); |
||||
fj_phone_normal.setPSTZ("J"); |
||||
|
||||
File file = new File(Environment.getExternalStorageDirectory(),RELATIVE_FJ_DIR+"phone_1.jpg"); |
||||
fj_phone_normal.setFJ(FileIOUtils.readFile2BytesByChannel(file)); |
||||
try { |
||||
fj_phone_normal.setFJHXZ(SM3Utils.sm3(file)); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
fj_phone_normal.setPSSJ("2022-10-18 15:42:56"); |
||||
//无人机时必填
|
||||
// fj_phone_normal.setJDGD(null);
|
||||
fj_phone_normal.setLongitude(119.9854700); |
||||
fj_phone_normal.setLatitude(30.2776150); |
||||
fj_phone_normal.setPSFYJ(41d); |
||||
fj_phone_normal.setPSJD(239d); |
||||
fj_phone_normal.setPSHGJ(2d); |
||||
fj_phone_normal.setPSJJ(27d); |
||||
fj_phone_normal.setXDGD(1.50d); |
||||
fj_phone_normal.setFJYSKD(1920); |
||||
fj_phone_normal.setFJYSGD(1080); |
||||
fj_phone_normal.setPSRY("test"); |
||||
|
||||
//为视频时必填
|
||||
// fj_phone_normal.setSPKZXX("");
|
||||
fj_phone_normal.setZSDM("1001"); |
||||
//附件信息上链时返回的交易ID
|
||||
// fj_phone_normal.setQKLDM(null);
|
||||
//校验码
|
||||
StringBuffer content = new StringBuffer(); |
||||
// FJHXZ,PSSJ,Longitude,Latitude,PSFYJ,PSJD,PSHGJ,PSRY,ZSDM
|
||||
content.append(fj_phone_normal.getFJHXZ()).append(","); |
||||
content.append(fj_phone_normal.getPSSJ()).append(","); |
||||
content.append(fj_phone_normal.getLongitude()).append(","); |
||||
content.append(fj_phone_normal.getLatitude()).append(","); |
||||
content.append(fj_phone_normal.getPSFYJ()).append(","); |
||||
content.append(fj_phone_normal.getPSJD()).append(","); |
||||
content.append(fj_phone_normal.getPSHGJ()).append(","); |
||||
content.append(fj_phone_normal.getPSRY()).append(","); |
||||
content.append(fj_phone_normal.getZSDM()); |
||||
String jym = Utils.makeJYM(content.toString(),Constants.TEST_PRIVATEKEY); |
||||
fj_phone_normal.setJYM(jym); |
||||
|
||||
// SM2SignVO verify = SM2SignVerUtils.VerifySignSM2(Util.hexStringToBytes(TEST_PUBLICKEY), SM3Utils.sm3(content.toString()).getBytes(StandardCharsets.UTF_8), Util.hexStringToBytes(jym));
|
||||
// System.out.println("验签得到的R值:"+verify.getVerify_r());
|
||||
// System.err.println("\n验签结果" +verify.isVerify());
|
||||
|
||||
FJ fj_phone_panoramic = new FJ(); |
||||
|
||||
fj_phone_panoramic.setBSM("2"); |
||||
fj_phone_panoramic.setTBLX("JCTB"); |
||||
fj_phone_panoramic.setTBBSM("8fd575622ffd45ff8ae9fba0b9c5ec21"); |
||||
fj_phone_panoramic.setXZQDM("110101"); |
||||
fj_phone_panoramic.setFJMC("110101"); |
||||
fj_phone_panoramic.setFJLX("2"); |
||||
fj_phone_panoramic.setPSTZ("J"); |
||||
|
||||
file = new File(Environment.getExternalStorageDirectory(),RELATIVE_FJ_DIR+"phone_panoramic_1.jpg"); |
||||
fj_phone_panoramic.setFJ(FileIOUtils.readFile2BytesByChannel(file)); |
||||
try { |
||||
fj_phone_panoramic.setFJHXZ(SM3Utils.sm3(file)); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
fj_phone_panoramic.setPSSJ("2022:10:18 15:43:50"); |
||||
//无人机时必填
|
||||
// fj_phone_panoramic.setJDGD(null);
|
||||
fj_phone_panoramic.setLongitude(119.9854813); |
||||
fj_phone_panoramic.setLatitude(30.2775860); |
||||
fj_phone_panoramic.setPSFYJ(26d); |
||||
fj_phone_panoramic.setPSJD(22d); |
||||
fj_phone_panoramic.setPSHGJ(-88d); |
||||
fj_phone_panoramic.setPSJJ(27d); |
||||
fj_phone_panoramic.setXDGD(1.50d); |
||||
fj_phone_panoramic.setFJYSKD(4096); |
||||
fj_phone_panoramic.setFJYSGD(2048); |
||||
fj_phone_panoramic.setPSRY("test"); |
||||
|
||||
//为视频时必填
|
||||
// fj_phone_panoramic.setSPKZXX("");
|
||||
fj_phone_panoramic.setZSDM("1001"); |
||||
//附件信息上链时返回的交易ID
|
||||
// fj_phone_panoramic.setQKLDM(null);
|
||||
//校验码
|
||||
content = new StringBuffer(); |
||||
// FJHXZ,PSSJ,Longitude,Latitude,PSFYJ,PSJD,PSHGJ,PSRY,ZSDM
|
||||
content.append(fj_phone_panoramic.getFJHXZ()).append(","); |
||||
content.append(fj_phone_panoramic.getPSSJ()).append(","); |
||||
content.append(fj_phone_panoramic.getLongitude()).append(","); |
||||
content.append(fj_phone_panoramic.getLatitude()).append(","); |
||||
content.append(fj_phone_panoramic.getPSFYJ()).append(","); |
||||
content.append(fj_phone_panoramic.getPSJD()).append(","); |
||||
content.append(fj_phone_panoramic.getPSHGJ()).append(","); |
||||
content.append(fj_phone_panoramic.getPSRY()).append(","); |
||||
content.append(fj_phone_panoramic.getZSDM()); |
||||
fj_phone_panoramic.setJYM(Utils.makeJYM(content.toString(),Constants.TEST_PRIVATEKEY)); |
||||
|
||||
FJ fj_uav_normal = new FJ(); |
||||
|
||||
fj_uav_normal.setBSM("3"); |
||||
fj_uav_normal.setTBLX("JCTB"); |
||||
fj_uav_normal.setTBBSM("8fd575622ffd45ff8ae9fba0b9c5ec23"); |
||||
fj_uav_normal.setXZQDM("110101"); |
||||
fj_uav_normal.setFJMC("110101"); |
||||
fj_uav_normal.setFJLX("1"); |
||||
fj_uav_normal.setPSTZ("J"); |
||||
|
||||
file = new File(Environment.getExternalStorageDirectory(),RELATIVE_FJ_DIR+"photo_uav_1658133414992.jpg"); |
||||
fj_uav_normal.setFJ(FileIOUtils.readFile2BytesByChannel(file)); |
||||
try { |
||||
fj_uav_normal.setFJHXZ(SM3Utils.sm3(file)); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
fj_uav_normal.setPSSJ("2022:07:18 16:35:21"); |
||||
//无人机时必填
|
||||
fj_uav_normal.setJDGD(-19d); |
||||
fj_uav_normal.setLongitude(119.9855061); |
||||
fj_uav_normal.setLatitude(30.2774821); |
||||
fj_uav_normal.setPSFYJ(-66d); |
||||
fj_uav_normal.setPSJD(337d); |
||||
fj_uav_normal.setPSHGJ(0d); |
||||
fj_uav_normal.setPSJJ(24d); |
||||
fj_uav_normal.setXDGD(111.00d); |
||||
fj_uav_normal.setFJYSKD(4000); |
||||
fj_uav_normal.setFJYSGD(2250); |
||||
fj_uav_normal.setPSRY("kmap"); |
||||
|
||||
//为视频时必填
|
||||
// fj_uav_normal.setSPKZXX("");
|
||||
fj_uav_normal.setZSDM("1001"); |
||||
//附件信息上链时返回的交易ID
|
||||
// fj_uav_normal.setQKLDM(null);
|
||||
//校验码
|
||||
content = new StringBuffer(); |
||||
// FJHXZ,PSSJ,Longitude,Latitude,PSFYJ,PSJD,PSHGJ,PSRY,ZSDM
|
||||
content.append(fj_uav_normal.getFJHXZ()).append(","); |
||||
content.append(fj_uav_normal.getPSSJ()).append(","); |
||||
content.append(fj_uav_normal.getLongitude()).append(","); |
||||
content.append(fj_uav_normal.getLatitude()).append(","); |
||||
content.append(fj_uav_normal.getPSFYJ()).append(","); |
||||
content.append(fj_uav_normal.getPSJD()).append(","); |
||||
content.append(fj_uav_normal.getPSHGJ()).append(","); |
||||
content.append(fj_uav_normal.getPSRY()).append(","); |
||||
content.append(fj_uav_normal.getZSDM()); |
||||
fj_uav_normal.setJYM(Utils.makeJYM(content.toString(),Constants.TEST_PRIVATEKEY)); |
||||
|
||||
|
||||
FJ fj_uav_panoramic = new FJ(); |
||||
|
||||
fj_uav_panoramic.setBSM("4"); |
||||
fj_uav_panoramic.setTBLX("JCTB"); |
||||
fj_uav_panoramic.setTBBSM("8fd575622ffd45ff8ae9fba0b9c5ec24"); |
||||
fj_uav_panoramic.setXZQDM("110101"); |
||||
fj_uav_panoramic.setFJMC("110101"); |
||||
fj_uav_panoramic.setFJLX("3"); |
||||
fj_uav_panoramic.setPSTZ("J"); |
||||
|
||||
file = new File(Environment.getExternalStorageDirectory(),RELATIVE_FJ_DIR+"photo_uav_1658133423647_panoramic.jpg"); |
||||
fj_uav_panoramic.setFJ(FileIOUtils.readFile2BytesByChannel(file)); |
||||
try { |
||||
fj_uav_panoramic.setFJHXZ(SM3Utils.sm3(file)); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
fj_uav_panoramic.setPSSJ("2022:07:18 16:36:44"); |
||||
//无人机时必填
|
||||
fj_uav_panoramic.setJDGD(-19d); |
||||
fj_uav_panoramic.setLongitude(119.9855061); |
||||
fj_uav_panoramic.setLatitude(30.2774821); |
||||
fj_uav_panoramic.setPSFYJ(-89d); |
||||
fj_uav_panoramic.setPSJD(337d); |
||||
fj_uav_panoramic.setPSHGJ(0d); |
||||
fj_uav_panoramic.setPSJJ(24d); |
||||
fj_uav_panoramic.setXDGD(112.00d); |
||||
fj_uav_panoramic.setFJYSKD(4096); |
||||
fj_uav_panoramic.setFJYSGD(2048); |
||||
fj_uav_panoramic.setPSRY("kmap"); |
||||
|
||||
//为视频时必填
|
||||
// fj_uav_panoramic.setSPKZXX("");
|
||||
fj_uav_panoramic.setZSDM("1001"); |
||||
//附件信息上链时返回的交易ID
|
||||
// fj_uav_panoramic.setQKLDM(null);
|
||||
//校验码
|
||||
content = new StringBuffer(); |
||||
// FJHXZ,PSSJ,Longitude,Latitude,PSFYJ,PSJD,PSHGJ,PSRY,ZSDM
|
||||
content.append(fj_uav_panoramic.getFJHXZ()).append(","); |
||||
content.append(fj_uav_panoramic.getPSSJ()).append(","); |
||||
content.append(fj_uav_panoramic.getLongitude()).append(","); |
||||
content.append(fj_uav_panoramic.getLatitude()).append(","); |
||||
content.append(fj_uav_panoramic.getPSFYJ()).append(","); |
||||
content.append(fj_uav_panoramic.getPSJD()).append(","); |
||||
content.append(fj_uav_panoramic.getPSHGJ()).append(","); |
||||
content.append(fj_uav_panoramic.getPSRY()).append(","); |
||||
content.append(fj_uav_panoramic.getZSDM()); |
||||
fj_uav_panoramic.setJYM(Utils.makeJYM(content.toString(),Constants.TEST_PRIVATEKEY)); |
||||
|
||||
FJ fj_video = new FJ(); |
||||
fj_video.setBSM("5"); |
||||
fj_video.setTBLX("JCTB"); |
||||
fj_video.setTBBSM("8fd575622ffd45ff8ae9fba0b9c5ec25"); |
||||
fj_video.setXZQDM("110101"); |
||||
fj_video.setFJMC("110101"); |
||||
fj_video.setFJLX("4"); |
||||
fj_video.setPSTZ("J"); |
||||
|
||||
file = new File(Environment.getExternalStorageDirectory(),RELATIVE_FJ_DIR+"phone_video_1.mp4"); |
||||
fj_video.setFJ(FileIOUtils.readFile2BytesByChannel(file)); |
||||
try { |
||||
fj_video.setFJHXZ(SM3Utils.sm3(file)); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
fj_video.setPSSJ("2022-10-18 15:43:09"); |
||||
//无人机时必填
|
||||
// fj_video.setJDGD(null);
|
||||
fj_video.setLongitude(119.9854736); |
||||
fj_video.setLatitude(30.2776146); |
||||
fj_video.setPSFYJ(15d); |
||||
fj_video.setPSJD(230d); |
||||
fj_video.setPSHGJ(0d); |
||||
fj_video.setPSJJ(27d); |
||||
fj_video.setXDGD(1.50d); |
||||
fj_video.setFJYSKD(480); |
||||
fj_video.setFJYSGD(360); |
||||
fj_video.setPSRY("test"); |
||||
|
||||
//为视频时必填
|
||||
fj_video.setSPKZXX("[{\"position\":1,\"x\":119.9854736,\"y\":30.27761460,\"angel\":230,\"height\":1.5},{\"position\":2,\"x\":119.985474,\"y\":30.27761460,\"angel\":232,\"height\":1.5},{\"position\":3,\"x\":119.9854736,\"y\":30.27761460,\"angel\":220,\"height\":1.5},{\"position\":4,\"x\":119.9854736,\"y\":30.27761459,\"angel\":231,\"height\":1.5},{\"position\":5,\"x\":119.9854736,\"y\":30.27761459,\"angel\":237,\"height\":1.5},{\"position\":6,\"x\":119.9854736,\"y\":30.27761459,\"angel\":246,\"height\":1.5},{\"position\":7,\"x\":119.9854736,\"y\":30.27761460,\"angel\":235,\"height\":1.5},{\"position\":8,\"x\":119.9854736,\"y\":30.27761459,\"angel\":213,\"height\":1.5},{\"position\":9,\"x\":119.9854736,\"y\":30.27761459,\"angel\":254,\"height\":1.5}]"); |
||||
fj_video.setZSDM("1001"); |
||||
//附件信息上链时返回的交易ID
|
||||
// fj_video.setQKLDM(null);
|
||||
//校验码
|
||||
content = new StringBuffer(); |
||||
// FJHXZ,PSSJ,Longitude,Latitude,PSFYJ,PSJD,PSHGJ,PSRY,ZSDM
|
||||
content.append(fj_video.getFJHXZ()).append(","); |
||||
content.append(fj_video.getPSSJ()).append(","); |
||||
content.append(fj_video.getLongitude()).append(","); |
||||
content.append(fj_video.getLatitude()).append(","); |
||||
content.append(fj_video.getPSFYJ()).append(","); |
||||
content.append(fj_video.getPSJD()).append(","); |
||||
content.append(fj_video.getPSHGJ()).append(","); |
||||
content.append(fj_video.getPSRY()).append(","); |
||||
content.append(fj_video.getZSDM()); |
||||
fj_video.setJYM(Utils.makeJYM(content.toString(),Constants.TEST_PRIVATEKEY)); |
||||
|
||||
|
||||
LandSurveyDatabase.getInstance().fjDao().insertFJ(fj_phone_normal,fj_phone_panoramic,fj_uav_normal,fj_uav_panoramic,fj_video); |
||||
// LandSurveyDatabase.getInstance().fjDao().insertFJ(fj_phone_normal,fj_phone_panoramic,fj_uav_normal);
|
||||
|
||||
} |
||||
|
||||
public void initDb(@NonNull Context context) { |
||||
try { |
||||
InputStream is = context.getAssets().open(DB_NAME); |
||||
File file = new File(Environment.getExternalStorageDirectory(), RELATIVE_PATH); |
||||
if (!file.exists() || !file.isFile()) { |
||||
file.getParentFile().mkdir(); |
||||
FileIOUtils.writeFileFromIS(file,is); |
||||
} |
||||
|
||||
is = context.getAssets().open(FJ_NAME_1); |
||||
file = new File(Environment.getExternalStorageDirectory(), RELATIVE_FJ_DIR+FJ_NAME_1); |
||||
if (!file.exists() || !file.isFile()) { |
||||
file.getParentFile().mkdir(); |
||||
FileIOUtils.writeFileFromIS(file,is); |
||||
} |
||||
is = context.getAssets().open(FJ_NAME_2); |
||||
file = new File(Environment.getExternalStorageDirectory(), RELATIVE_FJ_DIR+FJ_NAME_2); |
||||
if (!file.exists() || !file.isFile()) { |
||||
file.getParentFile().mkdir(); |
||||
FileIOUtils.writeFileFromIS(file,is); |
||||
} |
||||
is = context.getAssets().open(FJ_NAME_3); |
||||
file = new File(Environment.getExternalStorageDirectory(), RELATIVE_FJ_DIR+FJ_NAME_3); |
||||
if (!file.exists() || !file.isFile()) { |
||||
file.getParentFile().mkdir(); |
||||
FileIOUtils.writeFileFromIS(file,is); |
||||
} |
||||
is = context.getAssets().open(FJ_NAME_4); |
||||
file = new File(Environment.getExternalStorageDirectory(), RELATIVE_FJ_DIR+FJ_NAME_4); |
||||
if (!file.exists() || !file.isFile()) { |
||||
file.getParentFile().mkdir(); |
||||
FileIOUtils.writeFileFromIS(file,is); |
||||
} |
||||
is = context.getAssets().open(FJ_NAME_5); |
||||
file = new File(Environment.getExternalStorageDirectory(), RELATIVE_FJ_DIR+FJ_NAME_5); |
||||
if (!file.exists() || !file.isFile()) { |
||||
file.getParentFile().mkdir(); |
||||
FileIOUtils.writeFileFromIS(file,is); |
||||
} |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} finally { |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,52 @@ |
||||
package cn.org.landcloud.survey.data; |
||||
|
||||
|
||||
import androidx.room.Dao; |
||||
import androidx.room.Delete; |
||||
import androidx.room.Insert; |
||||
import androidx.room.OnConflictStrategy; |
||||
import androidx.room.Update; |
||||
|
||||
import java.util.List; |
||||
|
||||
import cn.org.landcloud.survey.data.bean.FJ; |
||||
|
||||
|
||||
@Dao |
||||
public interface FJDao { |
||||
|
||||
|
||||
/** |
||||
* 插入一条新的附件 |
||||
* 如插入时发生冲突,处理方式为插入一个新的对象。 |
||||
* @param fj |
||||
* @return |
||||
*/ |
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
long insertFJ(FJ fj); |
||||
|
||||
@Update |
||||
int updateFJ(FJ fj); |
||||
|
||||
@Delete |
||||
int deleteFJ(FJ fj); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertFJ(FJ... fj); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertFJ(List<FJ> fjs); |
||||
|
||||
@Update |
||||
void updateFJ(FJ... fj); |
||||
|
||||
@Update |
||||
void updateFJ(List<FJ> fj); |
||||
|
||||
@Delete |
||||
void deleteFJ(FJ... fj); |
||||
|
||||
@Delete |
||||
void deleteFJ(List<FJ> fj); |
||||
|
||||
} |
@ -0,0 +1,54 @@ |
||||
package cn.org.landcloud.survey.data; |
||||
|
||||
|
||||
import androidx.room.Dao; |
||||
import androidx.room.Delete; |
||||
import androidx.room.Insert; |
||||
import androidx.room.OnConflictStrategy; |
||||
import androidx.room.Update; |
||||
|
||||
import java.util.List; |
||||
|
||||
import cn.org.landcloud.survey.data.bean.JMXX; |
||||
import cn.org.landcloud.survey.data.bean.KZXXYSJ; |
||||
|
||||
|
||||
@Dao |
||||
public interface JMXXDao { |
||||
|
||||
|
||||
/** |
||||
* 插入一条新的附件 |
||||
* 如插入时发生冲突,处理方式为插入一个新的对象。 |
||||
* |
||||
* @param kzxxysj |
||||
* @return |
||||
*/ |
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
long insertJMXX(JMXX jmxx); |
||||
|
||||
@Update |
||||
int updateJMXX(JMXX jmxx); |
||||
|
||||
@Delete |
||||
int deleteJMXX(JMXX jmxx); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertKZXXYSJ(JMXX... jmxxs); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertJMXX(List<JMXX> jmxxList); |
||||
|
||||
@Update |
||||
void updateJMXX(JMXX... jmxxs); |
||||
|
||||
@Update |
||||
void updateJMXX(List<JMXX> jmxxList); |
||||
|
||||
@Delete |
||||
void deleteJMXX(JMXX... jmxxs); |
||||
|
||||
@Delete |
||||
void deleteJMXX(List<JMXX> jmxxList); |
||||
|
||||
} |
@ -0,0 +1,53 @@ |
||||
package cn.org.landcloud.survey.data; |
||||
|
||||
|
||||
import androidx.room.Dao; |
||||
import androidx.room.Delete; |
||||
import androidx.room.Insert; |
||||
import androidx.room.OnConflictStrategy; |
||||
import androidx.room.Update; |
||||
|
||||
import java.util.List; |
||||
|
||||
import cn.org.landcloud.survey.data.bean.KZXXYSJ; |
||||
|
||||
|
||||
@Dao |
||||
public interface KZXXYSJDao { |
||||
|
||||
|
||||
/** |
||||
* 插入一条新的附件 |
||||
* 如插入时发生冲突,处理方式为插入一个新的对象。 |
||||
* |
||||
* @param kzxxysj |
||||
* @return |
||||
*/ |
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
long insertKZXXYSJ(KZXXYSJ kzxxysj); |
||||
|
||||
@Update |
||||
int updateKZXXYSJ(KZXXYSJ kzxxysj); |
||||
|
||||
@Delete |
||||
int deleteKZXXYSJ(KZXXYSJ kzxxysj); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertKZXXYSJ(KZXXYSJ... kzxxysjs); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertKZXXYSJ(List<KZXXYSJ> kzxxysjList); |
||||
|
||||
@Update |
||||
void updateKZXXYSJ(KZXXYSJ... kzxxysjs); |
||||
|
||||
@Update |
||||
void updateKZXXYSJ(List<KZXXYSJ> kzxxysjList); |
||||
|
||||
@Delete |
||||
void deleteKZXXYSJ(KZXXYSJ... kzxxysjs); |
||||
|
||||
@Delete |
||||
void deleteKZXXYSJ(List<KZXXYSJ> kzxxysjList); |
||||
|
||||
} |
@ -0,0 +1,83 @@ |
||||
package cn.org.landcloud.survey.data; |
||||
|
||||
|
||||
import android.content.Context; |
||||
import android.text.TextUtils; |
||||
|
||||
import androidx.room.Database; |
||||
import androidx.room.Room; |
||||
import androidx.room.RoomDatabase; |
||||
|
||||
import cn.org.landcloud.survey.data.bean.DBInfo; |
||||
import cn.org.landcloud.survey.data.bean.DCHSXX; |
||||
import cn.org.landcloud.survey.data.bean.FJ; |
||||
import cn.org.landcloud.survey.data.bean.JMXX; |
||||
import cn.org.landcloud.survey.data.bean.KZXXYSJ; |
||||
import cn.org.landcloud.survey.data.bean.TBJBXX; |
||||
|
||||
@Database(entities = {DBInfo.class, DCHSXX.class, FJ.class, TBJBXX.class, KZXXYSJ.class, JMXX.class}, |
||||
version = 2, exportSchema = false) |
||||
public abstract class LandSurveyDatabase extends RoomDatabase { |
||||
|
||||
public static final String TABLE_NAME = "WYHCFJ"; |
||||
public static final String COLUMN_NAME_BSM = "F_ID"; |
||||
public static final String COLUMN_NAME_CONTENT = "FJ"; |
||||
|
||||
private static String sDbPath = null; |
||||
|
||||
private static volatile LandSurveyDatabase INSTANCE = null; |
||||
|
||||
private static Context mContext; |
||||
|
||||
/** |
||||
* 初始化AppDatabase参数 |
||||
* |
||||
* @param context 上下文引用 |
||||
* @param dbPath 数据库路径 |
||||
*/ |
||||
public static void init(Context context, String dbPath) { |
||||
mContext = context; |
||||
sDbPath = dbPath; |
||||
if (INSTANCE != null) { |
||||
INSTANCE.close(); |
||||
INSTANCE = null; |
||||
} |
||||
} |
||||
|
||||
|
||||
public static LandSurveyDatabase getInstance() { |
||||
if (INSTANCE == null) { |
||||
synchronized (LandSurveyDatabase.class) { |
||||
if (INSTANCE == null) { |
||||
INSTANCE = Room |
||||
.databaseBuilder(mContext.getApplicationContext(), LandSurveyDatabase.class, sDbPath) |
||||
.allowMainThreadQueries() |
||||
.build(); |
||||
} |
||||
|
||||
} |
||||
} |
||||
return (INSTANCE); |
||||
} |
||||
|
||||
public void destroy() { |
||||
if (INSTANCE != null) { |
||||
INSTANCE.close(); |
||||
INSTANCE = null; |
||||
} |
||||
} |
||||
|
||||
public abstract DBInfoDao dbInfoDao(); |
||||
|
||||
public abstract DCHSXXDao dchsxxDao(); |
||||
|
||||
public abstract FJDao fjDao(); |
||||
|
||||
public abstract KZXXYSJDao kzxxysjDao(); |
||||
|
||||
public abstract TBJBXXDao tbjbxxDao(); |
||||
|
||||
public abstract JMXXDao jmxxDao(); |
||||
|
||||
|
||||
} |
@ -0,0 +1,54 @@ |
||||
package cn.org.landcloud.survey.data; |
||||
|
||||
|
||||
import androidx.room.Dao; |
||||
import androidx.room.Delete; |
||||
import androidx.room.Insert; |
||||
import androidx.room.OnConflictStrategy; |
||||
import androidx.room.Update; |
||||
|
||||
import java.util.List; |
||||
|
||||
import cn.org.landcloud.survey.data.bean.KZXXYSJ; |
||||
import cn.org.landcloud.survey.data.bean.TBJBXX; |
||||
|
||||
|
||||
@Dao |
||||
public interface TBJBXXDao { |
||||
|
||||
|
||||
/** |
||||
* 插入一条新的附件 |
||||
* 如插入时发生冲突,处理方式为插入一个新的对象。 |
||||
* |
||||
* @param tbjbxx |
||||
* @return |
||||
*/ |
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
long insertTBJBXX(TBJBXX tbjbxx); |
||||
|
||||
@Update |
||||
int updateTBJBXX(TBJBXX tbjbxx); |
||||
|
||||
@Delete |
||||
int deleteTBJBXX(TBJBXX tbjbxx); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertTBJBXX(TBJBXX... tbjbxx); |
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||
void insertTBJBXX(List<TBJBXX> tbjbxxs); |
||||
|
||||
@Update |
||||
void updateTBJBXX(TBJBXX... tbjbxx); |
||||
|
||||
@Update |
||||
void updateTBJBXX(List<TBJBXX> tbjbxx); |
||||
|
||||
@Delete |
||||
void deleteTBJBXX(TBJBXX... tbjbxx); |
||||
|
||||
@Delete |
||||
void deleteTBJBXX(List<TBJBXX> tbjbxx); |
||||
|
||||
} |
@ -0,0 +1,87 @@ |
||||
package cn.org.landcloud.survey.data.bean; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.room.Entity; |
||||
import androidx.room.PrimaryKey; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Entity(tableName = "DB_INFO") |
||||
public class DBInfo implements Serializable { |
||||
|
||||
/** |
||||
* 版本号 |
||||
* 当前db包的格式规范的版本号,当前标准的版本为固定值1.0 |
||||
*/ |
||||
@PrimaryKey |
||||
@NonNull |
||||
private String version; |
||||
|
||||
/** |
||||
* 创建时间: |
||||
* Db包创建时间,格式:yyyy-MM-dd HH:mm:ss |
||||
*/ |
||||
private String createtime; |
||||
|
||||
/** |
||||
* 修改时间: |
||||
* Db包修改时间,格式:yyyy-MM-dd HH:mm:ss |
||||
*/ |
||||
private String updatetime; |
||||
|
||||
/** |
||||
* 生成人员: |
||||
* Db包创建人员 |
||||
*/ |
||||
private String createuser; |
||||
|
||||
/** |
||||
* 描述信息: |
||||
* Db包的描述 |
||||
*/ |
||||
private String description; |
||||
|
||||
public DBInfo() { |
||||
} |
||||
|
||||
public String getVersion() { |
||||
return version; |
||||
} |
||||
|
||||
public void setVersion(String version) { |
||||
this.version = version; |
||||
} |
||||
|
||||
public String getCreatetime() { |
||||
return createtime; |
||||
} |
||||
|
||||
public void setCreatetime(String createtime) { |
||||
this.createtime = createtime; |
||||
} |
||||
|
||||
public String getUpdatetime() { |
||||
return updatetime; |
||||
} |
||||
|
||||
public void setUpdatetime(String updatetime) { |
||||
this.updatetime = updatetime; |
||||
} |
||||
|
||||
public String getCreateuser() { |
||||
return createuser; |
||||
} |
||||
|
||||
public void setCreateuser(String createuser) { |
||||
this.createuser = createuser; |
||||
} |
||||
|
||||
public String getDescription() { |
||||
return description; |
||||
} |
||||
|
||||
public void setDescription(String description) { |
||||
this.description = description; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,89 @@ |
||||
package cn.org.landcloud.survey.data.bean; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.room.Entity; |
||||
import androidx.room.PrimaryKey; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 调查核实信息表 |
||||
*/ |
||||
@Entity(tableName = "DCHSXX") |
||||
public class DCHSXX implements Serializable { |
||||
|
||||
/** |
||||
* 地块标识码: |
||||
* 主键,地块基本信息表中的地块标识码 |
||||
*/ |
||||
@PrimaryKey |
||||
@NonNull |
||||
private String TBBSM; |
||||
|
||||
/** |
||||
* 外业核实情况 |
||||
*/ |
||||
private String WYHSQK; |
||||
|
||||
/** |
||||
* 扩展信息: |
||||
* 扩展信息,json字符串。根据元数据表进行描述 |
||||
*/ |
||||
private String KZXX; |
||||
|
||||
/** |
||||
* 调查人员 |
||||
*/ |
||||
@NonNull |
||||
private String DCRY; |
||||
|
||||
/** |
||||
* 调查时间: |
||||
* 精确到秒,格式:yyyy-MM-dd HH:mm:ss |
||||
*/ |
||||
@NonNull |
||||
private String DCSJ; |
||||
|
||||
public DCHSXX() { |
||||
} |
||||
|
||||
public String getTBBSM() { |
||||
return TBBSM; |
||||
} |
||||
|
||||
public void setTBBSM(String TBBSM) { |
||||
this.TBBSM = TBBSM; |
||||
} |
||||
|
||||
public String getWYHSQK() { |
||||
return WYHSQK; |
||||
} |
||||
|
||||
public void setWYHSQK(String WYHSQK) { |
||||
this.WYHSQK = WYHSQK; |
||||
} |
||||
|
||||
public String getKZXX() { |
||||
return KZXX; |
||||
} |
||||
|
||||
public void setKZXX(String KZXX) { |
||||
this.KZXX = KZXX; |
||||
} |
||||
|
||||
public String getDCRY() { |
||||
return DCRY; |
||||
} |
||||
|
||||
public void setDCRY(String DCRY) { |
||||
this.DCRY = DCRY; |
||||
} |
||||
|
||||
public String getDCSJ() { |
||||
return DCSJ; |
||||
} |
||||
|
||||
public void setDCSJ(String DCSJ) { |
||||
this.DCSJ = DCSJ; |
||||
} |
||||
} |
@ -0,0 +1,395 @@ |
||||
package cn.org.landcloud.survey.data.bean; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.room.Entity; |
||||
import androidx.room.PrimaryKey; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 附件表实体类 |
||||
*/ |
||||
@Entity(tableName = "FJ") |
||||
public class FJ implements Serializable { |
||||
|
||||
/** |
||||
* 标识码,主键 |
||||
*/ |
||||
@PrimaryKey |
||||
@NonNull |
||||
private String BSM; |
||||
|
||||
/** |
||||
* 地块类型 |
||||
*/ |
||||
@NonNull |
||||
private String TBLX; |
||||
|
||||
/** |
||||
* 地块标识码: |
||||
* 地块基本信息表中的标识码字段 |
||||
*/ |
||||
@NonNull |
||||
private String TBBSM; |
||||
|
||||
/** |
||||
* 县级行政区代码: |
||||
* 6位县级行政区代码 |
||||
*/ |
||||
@NonNull |
||||
private String XZQDM; |
||||
|
||||
/** |
||||
* 附件名称: |
||||
* 需带格式后缀,如*.jpg、*.png、*.mp4等 |
||||
*/ |
||||
private String FJMC; |
||||
|
||||
/** |
||||
* 附件类型: |
||||
* 0:手机照片;1:无人机照片;2:手机全景;3:无人机全景;4:手机视频。 |
||||
* 默认为0 |
||||
*/ |
||||
@NonNull |
||||
private String FJLX; |
||||
|
||||
/** |
||||
* 拍摄特征: |
||||
* Y:远景 |
||||
* J:近景 |
||||
* T:局部特征 |
||||
*/ |
||||
@NonNull |
||||
private String PSTZ; |
||||
|
||||
/** |
||||
* 附件: |
||||
* 文件内容的二进制存储 |
||||
*/ |
||||
@NonNull |
||||
private byte[] FJ; |
||||
|
||||
/** |
||||
* 附件哈希值: |
||||
* 附件的哈希值是对文件的内容采用国密SM3计算哈希值 |
||||
*/ |
||||
@NonNull |
||||
private String FJHXZ; |
||||
|
||||
/** |
||||
* 拍摄时间: |
||||
* 精确到秒,格式:yyyy-MM-dd HH:mm:ss |
||||
*/ |
||||
@NonNull |
||||
private String PSSJ; |
||||
|
||||
/** |
||||
* 拍摄相对高度: |
||||
* 单位为米,保留2位小数。当为无人机拍摄时高度为无人机的相对高度,当为手机拍摄时一般为拍摄人员的身高 |
||||
*/ |
||||
@NonNull |
||||
private Double XDGD; |
||||
|
||||
/** |
||||
* 拍摄绝对高度: |
||||
* 拍摄点相对海平面的高度,单位为米,保留2位小数。当为无人机拍摄时必填 |
||||
*/ |
||||
private Double JDGD; |
||||
|
||||
/** |
||||
* 拍摄点经度: |
||||
* CGCS2000球面坐标,保留7位小数 |
||||
*/ |
||||
@NonNull |
||||
private Double Longitude; |
||||
|
||||
/** |
||||
* 拍摄点纬度: |
||||
* CGCS2000球面坐标,保留7位小数 |
||||
*/ |
||||
@NonNull |
||||
private Double Latitude; |
||||
|
||||
/** |
||||
* 拍摄俯仰角: |
||||
* 俯仰角(pitch),无人机取值一般为[-90,0]手机取值为[-180,180],上翻为正由0至180,下翻为负由0至-180。无人机一般用相机的角度代替。 |
||||
*/ |
||||
@NonNull |
||||
private Double PSFYJ; |
||||
|
||||
/** |
||||
* 拍摄角度: |
||||
* 方向角(yaw),值域范围[0,360],正北为0,顺时针方向递增至360 |
||||
*/ |
||||
@NonNull |
||||
private Double PSJD; |
||||
|
||||
/** |
||||
* 拍摄横滚角: |
||||
* 横滚角(roll),值域范围[-180,180],向右滚为正由0至180,左滚为负0至-180。无人机为0 |
||||
*/ |
||||
@NonNull |
||||
private Double PSHGJ; |
||||
|
||||
/** |
||||
* 拍摄焦距: |
||||
* 35mm等效焦距,单位mm,当附件类型为[0:手机照片]、[1:无人机照片]时必填。 |
||||
*/ |
||||
private Double PSJJ; |
||||
|
||||
/** |
||||
* 附件原始宽度: |
||||
* 照片压缩前的原始分辨率-宽,当附件类型为[0:手机照片]、[1:无人机照片]时必填。 |
||||
*/ |
||||
private Integer FJYSKD; |
||||
|
||||
/** |
||||
* 附件原始高度: |
||||
* 照片压缩前的原始分辨率-高,当附件类型为[0:手机照片]、[1:无人机照片]时必填。 |
||||
*/ |
||||
private Integer FJYSGD; |
||||
|
||||
/** |
||||
* 拍摄人员: |
||||
* 拍照人员的姓名 |
||||
*/ |
||||
@NonNull |
||||
private String PSRY; |
||||
|
||||
/** |
||||
* 视频扩展信息: |
||||
* JSON字符串,记录视频拍摄每秒的位置、方向等信息。当附件类型为[4:手机视频]时必填。 |
||||
* [ |
||||
* {position:时间,x:经度,y:纬度,angel:方位角,height:高度}, |
||||
* {position:时间,x:经度,y:纬度,angel:方位角,height:高度}, |
||||
* {position:时间,x:经度,y:纬度,angel:方位角,height:高度} |
||||
* ] |
||||
* 其中x,y经纬度为2000球面坐标系,保留7位小数,position为视频的时间位置,单位秒,方位角为度,height为高度,单位为米,保留2位小数;angel为方位角,为手机的镜头的方向,通过yaw、pitch、roll三个值综合计算得出,正北为0,顺时针旋转到360。 |
||||
* 注:当附件类型为视频时,相关参数为拍摄开始时的参数。 |
||||
*/ |
||||
private String SPKZXX; |
||||
|
||||
/** |
||||
* 证书代码: |
||||
* 参考加密信息表证书代码 |
||||
*/ |
||||
@NonNull |
||||
private String ZSDM; |
||||
|
||||
/** |
||||
* 区块链代码: |
||||
* 附件信息上链时返回的交易ID |
||||
*/ |
||||
private String QKLDM; |
||||
|
||||
/** |
||||
* 校验码: |
||||
* 用于校验数据的真伪,通过上面的信息 |
||||
*/ |
||||
@NonNull |
||||
private String JYM; |
||||
|
||||
|
||||
public FJ() { |
||||
} |
||||
|
||||
public String getBSM() { |
||||
return BSM; |
||||
} |
||||
|
||||
public void setBSM(String BSM) { |
||||
this.BSM = BSM; |
||||
} |
||||
|
||||
public String getTBLX() { |
||||
return TBLX; |
||||
} |
||||
|
||||
public void setTBLX(String TBLX) { |
||||
this.TBLX = TBLX; |
||||
} |
||||
|
||||
public String getTBBSM() { |
||||
return TBBSM; |
||||
} |
||||
|
||||
public void setTBBSM(String TBBSM) { |
||||
this.TBBSM = TBBSM; |
||||
} |
||||
|
||||
public String getXZQDM() { |
||||
return XZQDM; |
||||
} |
||||
|
||||
public void setXZQDM(String XZQDM) { |
||||
this.XZQDM = XZQDM; |
||||
} |
||||
|
||||
public String getFJMC() { |
||||
return FJMC; |
||||
} |
||||
|
||||
public void setFJMC(String FJMC) { |
||||
this.FJMC = FJMC; |
||||
} |
||||
|
||||
public String getFJLX() { |
||||
return FJLX; |
||||
} |
||||
|
||||
public void setFJLX(String FJLX) { |
||||
this.FJLX = FJLX; |
||||
} |
||||
|
||||
public String getPSTZ() { |
||||
return PSTZ; |
||||
} |
||||
|
||||
public void setPSTZ(String PSTZ) { |
||||
this.PSTZ = PSTZ; |
||||
} |
||||
|
||||
public byte[] getFJ() { |
||||
return FJ; |
||||
} |
||||
|
||||
public void setFJ(byte[] FJ) { |
||||
this.FJ = FJ; |
||||
} |
||||
|
||||
public String getFJHXZ() { |
||||
return FJHXZ; |
||||
} |
||||
|
||||
public void setFJHXZ(String FJHXZ) { |
||||
this.FJHXZ = FJHXZ; |
||||
} |
||||
|
||||
public String getPSSJ() { |
||||
return PSSJ; |
||||
} |
||||
|
||||
public void setPSSJ(String PSSJ) { |
||||
this.PSSJ = PSSJ; |
||||
} |
||||
|
||||
public Double getXDGD() { |
||||
return XDGD; |
||||
} |
||||
|
||||
public void setXDGD(Double XDGD) { |
||||
this.XDGD = XDGD; |
||||
} |
||||
|
||||
public Double getJDGD() { |
||||
return JDGD; |
||||
} |
||||
|
||||
public void setJDGD(Double JDGD) { |
||||
this.JDGD = JDGD; |
||||
} |
||||
|
||||
public Double getLongitude() { |
||||
return Longitude; |
||||
} |
||||
|
||||
public void setLongitude(Double longitude) { |
||||
Longitude = longitude; |
||||
} |
||||
|
||||
public Double getLatitude() { |
||||
return Latitude; |
||||
} |
||||
|
||||
public void setLatitude(Double latitude) { |
||||
Latitude = latitude; |
||||
} |
||||
|
||||
public Double getPSFYJ() { |
||||
return PSFYJ; |
||||
} |
||||
|
||||
public void setPSFYJ(Double PSFYJ) { |
||||
this.PSFYJ = PSFYJ; |
||||
} |
||||
|
||||
public Double getPSJD() { |
||||
return PSJD; |
||||
} |
||||
|
||||
public void setPSJD(Double PSJD) { |
||||
this.PSJD = PSJD; |
||||
} |
||||
|
||||
public Double getPSHGJ() { |
||||
return PSHGJ; |
||||
} |
||||
|
||||
public void setPSHGJ(Double PSHGJ) { |
||||
this.PSHGJ = PSHGJ; |
||||
} |
||||
|
||||
public Double getPSJJ() { |
||||
return PSJJ; |
||||
} |
||||
|
||||
public void setPSJJ(Double PSJJ) { |
||||
this.PSJJ = PSJJ; |
||||
} |
||||
|
||||
public Integer getFJYSKD() { |
||||
return FJYSKD; |
||||
} |
||||
|
||||
public void setFJYSKD(Integer FJYSKD) { |
||||
this.FJYSKD = FJYSKD; |
||||
} |
||||
|
||||
public Integer getFJYSGD() { |
||||
return FJYSGD; |
||||
} |
||||
|
||||
public void setFJYSGD(Integer FJYSGD) { |
||||
this.FJYSGD = FJYSGD; |
||||
} |
||||
|
||||
public String getPSRY() { |
||||
return PSRY; |
||||
} |
||||
|
||||
public void setPSRY(String PSRY) { |
||||
this.PSRY = PSRY; |
||||
} |
||||
|
||||
public String getSPKZXX() { |
||||
return SPKZXX; |
||||
} |
||||
|
||||
public void setSPKZXX(String SPKZXX) { |
||||
this.SPKZXX = SPKZXX; |
||||
} |
||||
|
||||
public String getZSDM() { |
||||
return ZSDM; |
||||
} |
||||
|
||||
public void setZSDM(String ZSDM) { |
||||
this.ZSDM = ZSDM; |
||||
} |
||||
|
||||
public String getQKLDM() { |
||||
return QKLDM; |
||||
} |
||||
|
||||
public void setQKLDM(String QKLDM) { |
||||
this.QKLDM = QKLDM; |
||||
} |
||||
|
||||
public String getJYM() { |
||||
return JYM; |
||||
} |
||||
|
||||
public void setJYM(String JYM) { |
||||
this.JYM = JYM; |
||||
} |
||||
} |
@ -0,0 +1,91 @@ |
||||
package cn.org.landcloud.survey.data.bean; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.room.Entity; |
||||
import androidx.room.PrimaryKey; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
@Entity(tableName = "JMXX") |
||||
public class JMXX implements Serializable { |
||||
|
||||
/** |
||||
* 证书代码: |
||||
* 主键,在证书颁发时生成 |
||||
*/ |
||||
@PrimaryKey |
||||
@NonNull |
||||
private String ZSDM; |
||||
|
||||
/** |
||||
* 数字证书: |
||||
* 数字证书文件的内容,base64编码的字符串 |
||||
*/ |
||||
@NonNull |
||||
private String SZZS; |
||||
|
||||
/** |
||||
* 证书颁发机构代码: |
||||
* 颁发证书机构的统一信用代码 |
||||
*/ |
||||
@NonNull |
||||
private String ZSBFJGDM; |
||||
|
||||
/** |
||||
* 证书颁发机构公钥: |
||||
* 颁发证书机构的公开公钥,用于验证和解密数字证书 |
||||
*/ |
||||
private String ZSBFJGGY; |
||||
|
||||
/** |
||||
* 区块链访问地址: |
||||
* 区块链访问接口根地址 |
||||
*/ |
||||
private String QKLFWDZ; |
||||
|
||||
public JMXX() { |
||||
} |
||||
|
||||
@NonNull |
||||
public String getZSDM() { |
||||
return ZSDM; |
||||
} |
||||
|
||||
public void setZSDM(@NonNull String ZSDM) { |
||||
this.ZSDM = ZSDM; |
||||
} |
||||
|
||||
@NonNull |
||||
public String getSZZS() { |
||||
return SZZS; |
||||
} |
||||
|
||||
public void setSZZS(@NonNull String SZZS) { |
||||
this.SZZS = SZZS; |
||||
} |
||||
|
||||
@NonNull |
||||
public String getZSBFJGDM() { |
||||
return ZSBFJGDM; |
||||
} |
||||
|
||||
public void setZSBFJGDM(@NonNull String ZSBFJGDM) { |
||||
this.ZSBFJGDM = ZSBFJGDM; |
||||
} |
||||
|
||||
public String getZSBFJGGY() { |
||||
return ZSBFJGGY; |
||||
} |
||||
|
||||
public void setZSBFJGGY(String ZSBFJGGY) { |
||||
this.ZSBFJGGY = ZSBFJGGY; |
||||
} |
||||
|
||||
public String getQKLFWDZ() { |
||||
return QKLFWDZ; |
||||
} |
||||
|
||||
public void setQKLFWDZ(String QKLFWDZ) { |
||||
this.QKLFWDZ = QKLFWDZ; |
||||
} |
||||
} |
@ -0,0 +1,166 @@ |
||||
package cn.org.landcloud.survey.data.bean; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.room.ColumnInfo; |
||||
import androidx.room.Entity; |
||||
import androidx.room.PrimaryKey; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
|
||||
/** |
||||
* 扩展信息元数据表 |
||||
*/ |
||||
@Entity(tableName = "KZXXYSJ") |
||||
public class KZXXYSJ implements Serializable { |
||||
|
||||
/** |
||||
* 标识码: |
||||
* 主键 |
||||
*/ |
||||
@PrimaryKey(autoGenerate = false) |
||||
@NonNull |
||||
private Integer BSM; |
||||
|
||||
/** |
||||
* 地块类型: |
||||
* 地块类型,例如:JCTB,SSNYD |
||||
*/ |
||||
@NonNull |
||||
private String TBLX; |
||||
|
||||
/** |
||||
* 字段名称 |
||||
*/ |
||||
@NonNull |
||||
private String ZDMC; |
||||
|
||||
/** |
||||
* 字段别名,字段的别名,一般是中文名称 |
||||
*/ |
||||
@NonNull |
||||
private String ZDBM; |
||||
|
||||
/** |
||||
* 字段描述: |
||||
* 字段的中文描述 |
||||
*/ |
||||
private String ZDMS; |
||||
|
||||
/** |
||||
* 字段类型: |
||||
* INTEGER:整数、TEXT:文本、REAL:数字 |
||||
*/ |
||||
@NonNull |
||||
private String ZDLX; |
||||
|
||||
/** |
||||
* 字段长度 |
||||
*/ |
||||
private Integer ZDCD; |
||||
|
||||
/** |
||||
* 是否必填: |
||||
* 是否必填。 Y:是,N:否 |
||||
*/ |
||||
@NonNull |
||||
private String SFBT; |
||||
|
||||
/** |
||||
* 数据字典: |
||||
* 当字段类型为DIC时,该字段必填, |
||||
* 具体格式如下:[{code:”01”,description:”字典值1的描述”},{code:”02”,description:”字典值2的描述”},{code:”03”,description:”字典值3的描述”}],其中code为字典值,description为字典值的描述,两者都是文本类型;当字典值可多选时,对应值用英文逗号拼接,例如:”03,04”。 |
||||
*/ |
||||
private String SJZD; |
||||
|
||||
/** |
||||
* 扩展信息类型: |
||||
* JBXX:基本信息的扩展信息字段 |
||||
* DCXX:调查信息扩展信息字段 |
||||
*/ |
||||
@NonNull |
||||
private String KZXXLX; |
||||
|
||||
public KZXXYSJ() { |
||||
} |
||||
|
||||
public Integer getBSM() { |
||||
return BSM; |
||||
} |
||||
|
||||
public void setBSM(Integer BSM) { |
||||
this.BSM = BSM; |
||||
} |
||||
|
||||
public String getTBLX() { |
||||
return TBLX; |
||||
} |
||||
|
||||
public void setTBLX(String TBLX) { |
||||
this.TBLX = TBLX; |
||||
} |
||||
|
||||
public String getZDMC() { |
||||
return ZDMC; |
||||
} |
||||
|
||||
public void setZDMC(String ZDMC) { |
||||
this.ZDMC = ZDMC; |
||||
} |
||||
|
||||
public String getZDMS() { |
||||
return ZDMS; |
||||
} |
||||
|
||||
public void setZDMS(String ZDMS) { |
||||
this.ZDMS = ZDMS; |
||||
} |
||||
|
||||
public String getZDLX() { |
||||
return ZDLX; |
||||
} |
||||
|
||||
public void setZDLX(String ZDLX) { |
||||
this.ZDLX = ZDLX; |
||||
} |
||||
|
||||
public Integer getZDCD() { |
||||
return ZDCD; |
||||
} |
||||
|
||||
public void setZDCD(Integer ZDCD) { |
||||
this.ZDCD = ZDCD; |
||||
} |
||||
|
||||
public String getSFBT() { |
||||
return SFBT; |
||||
} |
||||
|
||||
public void setSFBT(String SFBT) { |
||||
this.SFBT = SFBT; |
||||
} |
||||
|
||||
public String getKZXXLX() { |
||||
return KZXXLX; |
||||
} |
||||
|
||||
public void setKZXXLX(String KZXXLX) { |
||||
this.KZXXLX = KZXXLX; |
||||
} |
||||
|
||||
public String getSJZD() { |
||||
return SJZD; |
||||
} |
||||
|
||||
public void setSJZD(String SJZD) { |
||||
this.SJZD = SJZD; |
||||
} |
||||
|
||||
public String getZDBM() { |
||||
return ZDBM; |
||||
} |
||||
|
||||
public void setZDBM(String ZDBM) { |
||||
this.ZDBM = ZDBM; |
||||
} |
||||
} |
@ -0,0 +1,192 @@ |
||||
package cn.org.landcloud.survey.data.bean; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.room.Entity; |
||||
import androidx.room.Index; |
||||
import androidx.room.PrimaryKey; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 地块基本信息表 |
||||
*/ |
||||
@Entity(tableName = "TBJBXX",indices = {@Index(name = "uidx_tbjbxx_tblx_xzqdm_tbbh", value = {"TBLX","XZQDM","TBBH"} ,unique = true)}) |
||||
public class TBJBXX implements Serializable { |
||||
|
||||
/** |
||||
* 标识码: |
||||
* 地块标识码。主键,全局唯一,建议使用GUID |
||||
*/ |
||||
@NonNull |
||||
@PrimaryKey |
||||
private String BSM; |
||||
|
||||
/** |
||||
* 地块类型 |
||||
*/ |
||||
@NonNull |
||||
private String TBLX; |
||||
|
||||
/** |
||||
* 县级行政区代码 |
||||
*/ |
||||
@NonNull |
||||
private String XZQDM; |
||||
|
||||
/** |
||||
* 县级行政区名称 |
||||
*/ |
||||
@NonNull |
||||
private String XMC; |
||||
|
||||
/** |
||||
* 地块编号: |
||||
* 区县唯一 |
||||
*/ |
||||
@NonNull |
||||
private String TBBH; |
||||
|
||||
/** |
||||
* 地块名称 |
||||
*/ |
||||
private String TBMC; |
||||
|
||||
/** |
||||
* 地块面积: |
||||
* 单位:亩,保留2位小数 |
||||
*/ |
||||
@NonNull |
||||
private double TBMJ; |
||||
|
||||
/** |
||||
* X坐标: |
||||
* 投影参考为:CGCS2000平面坐标,含带号,保留3位小数 |
||||
*/ |
||||
@NonNull |
||||
private double XZB; |
||||
|
||||
/** |
||||
* Y坐标: |
||||
* 投影参考为:CGCS2000平面坐标,含带号,保留3位小数 |
||||
*/ |
||||
@NonNull |
||||
private double YZB; |
||||
|
||||
/** |
||||
* 备注: |
||||
* 选填,样本地类编码 |
||||
*/ |
||||
private String BZ; |
||||
|
||||
/** |
||||
* 扩展信息: |
||||
* 扩展信息,json字符串。根据元数据表进行描述 |
||||
*/ |
||||
private String KZXX; |
||||
|
||||
/** |
||||
* 地块范围: |
||||
* 地块边界,标准WKT格式,投影参考为:CGCS2000平面坐标,带带号 |
||||
*/ |
||||
@NonNull |
||||
private String TBFW; |
||||
|
||||
public TBJBXX() { |
||||
} |
||||
|
||||
public String getBSM() { |
||||
return BSM; |
||||
} |
||||
|
||||
public void setBSM(String BSM) { |
||||
this.BSM = BSM; |
||||
} |
||||
|
||||
public String getTBLX() { |
||||
return TBLX; |
||||
} |
||||
|
||||
public void setTBLX(String TBLX) { |
||||
this.TBLX = TBLX; |
||||
} |
||||
|
||||
public String getXZQDM() { |
||||
return XZQDM; |
||||
} |
||||
|
||||
public void setXZQDM(String XZQDM) { |
||||
this.XZQDM = XZQDM; |
||||
} |
||||
|
||||
public String getXMC() { |
||||
return XMC; |
||||
} |
||||
|
||||
public void setXMC(String XMC) { |
||||
this.XMC = XMC; |
||||
} |
||||
|
||||
public String getTBBH() { |
||||
return TBBH; |
||||
} |
||||
|
||||
public void setTBBH(String TBBH) { |
||||
this.TBBH = TBBH; |
||||
} |
||||
|
||||
public String getTBMC() { |
||||
return TBMC; |
||||
} |
||||
|
||||
public void setTBMC(String TBMC) { |
||||
this.TBMC = TBMC; |
||||
} |
||||
|
||||
public double getTBMJ() { |
||||
return TBMJ; |
||||
} |
||||
|
||||
public void setTBMJ(double TBMJ) { |
||||
this.TBMJ = TBMJ; |
||||
} |
||||
|
||||
public double getXZB() { |
||||
return XZB; |
||||
} |
||||
|
||||
public void setXZB(double XZB) { |
||||
this.XZB = XZB; |
||||
} |
||||
|
||||
public double getYZB() { |
||||
return YZB; |
||||
} |
||||
|
||||
public void setYZB(double YZB) { |
||||
this.YZB = YZB; |
||||
} |
||||
|
||||
public String getBZ() { |
||||
return BZ; |
||||
} |
||||
|
||||
public void setBZ(String BZ) { |
||||
this.BZ = BZ; |
||||
} |
||||
|
||||
public String getKZXX() { |
||||
return KZXX; |
||||
} |
||||
|
||||
public void setKZXX(String KZXX) { |
||||
this.KZXX = KZXX; |
||||
} |
||||
|
||||
public String getTBFW() { |
||||
return TBFW; |
||||
} |
||||
|
||||
public void setTBFW(String TBFW) { |
||||
this.TBFW = TBFW; |
||||
} |
||||
} |
@ -0,0 +1,54 @@ |
||||
package cn.org.landcloud.survey.util; |
||||
|
||||
import java.io.Closeable; |
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* <pre> |
||||
* author: Blankj |
||||
* blog : http://blankj.com
|
||||
* time : 2016/10/09 |
||||
* desc : 关闭相关工具类 |
||||
* </pre> |
||||
*/ |
||||
public final class CloseUtils { |
||||
|
||||
private CloseUtils() { |
||||
throw new UnsupportedOperationException("u can't instantiate me..."); |
||||
} |
||||
|
||||
/** |
||||
* 关闭IO |
||||
* |
||||
* @param closeables closeables |
||||
*/ |
||||
public static void closeIO(final Closeable... closeables) { |
||||
if (closeables == null) return; |
||||
for (Closeable closeable : closeables) { |
||||
if (closeable != null) { |
||||
try { |
||||
closeable.close(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 安静关闭IO |
||||
* |
||||
* @param closeables closeables |
||||
*/ |
||||
public static void closeIOQuietly(final Closeable... closeables) { |
||||
if (closeables == null) return; |
||||
for (Closeable closeable : closeables) { |
||||
if (closeable != null) { |
||||
try { |
||||
closeable.close(); |
||||
} catch (IOException ignored) { |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
package cn.org.landcloud.survey.util; |
||||
|
||||
public class Constants { |
||||
|
||||
public static final String TEST_CER = "eyJjZXJ0Y29kZSI6IjEwMDEiLCJjZXJ0b3JnY29kZSI6IjEyMTAwMDAwNDAwMDEwMzk4UCIsImNlcnRvcmduYW1lIjoi5Lit5Zu95Zu95Zyf5YuY5rWL6KeE5YiS6ZmiIiwiZXhwaXJhdGlvbiI6IjE2OTcyNjkwNTEiLCJzaWduIjoiMzA0NDAyMjAxMkY5MThBRDdBODdEMTQ4MEU4ODZCMzlGOTQ3OTkxQjRFMUExQzBDNUM2MEU3QTVFRTM0M0Y1Rjg2QUE2QjE3MDIyMDM1M0I4Q0ZDQ0QyMjQ0QzM4NDRFMTc5QjM4OEY3ODIwMTBFRjE2RTRBMENFNTU5MDUzM0M3ODA0MjhBNTMyNjEiLCJvcmdjb2RlIjoiOTEzMzAxMTA2Nzk4ODU5NDAxIiwib3JnbmFtZSI6IuadreW3nuS7iuWlpeS/oeaBr+enkeaKgOiCoeS7veaciemZkOWFrOWPuCIsInB1YmxpY2tleSI6IjA0NzgyOEQ1NDY2QUI2QUYyMUZEODUyOEE5MDE2MjJBRTEwMEEzRUQ4MEUyQUZFRkFBMDkzQkVERjM2NjJDNTMyNzMwNURBQTBBODUzNzcwQkEwNjA1RjYyNjZCMDU1MzVFQ0NDNzc0N0JBQTEyMkYxODVDNDdEOUY2NUU3NEU2MEMifQ=="; |
||||
public static final String TEST_PRIVATEKEY= "00D7D395E6093C63A50A0370D5F6CD89964AB148A846EA96C9969AF08EC1E97513"; |
||||
public static final String TEST_PUBLICKEY= "047828D5466AB6AF21FD8528A901622AE100A3ED80E2AFEFAA093BEDF3662C5327305DAA0A853770BA0605F6266B05535ECCC7747BAA122F185C47D9F65E74E60C"; |
||||
public static final String TEST_CERT_ORG_PUBLICKEY= "048D9B68E8DECD33A19A73F87169BB4A65BFE557AA1F58462BAF5D63EFBC5EE5385D1184C3B2A5A0D6EE2ED401182D0E6AF362DCAA8931231399D941AD318D21AD"; |
||||
public static final String CERT_ORG_CODE = "12100000400010398P"; |
||||
} |
@ -0,0 +1,707 @@ |
||||
package cn.org.landcloud.survey.util; |
||||
|
||||
import java.io.BufferedOutputStream; |
||||
import java.io.BufferedReader; |
||||
import java.io.BufferedWriter; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileOutputStream; |
||||
import java.io.FileWriter; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.InputStreamReader; |
||||
import java.io.OutputStream; |
||||
import java.io.RandomAccessFile; |
||||
import java.nio.ByteBuffer; |
||||
import java.nio.MappedByteBuffer; |
||||
import java.nio.channels.FileChannel; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import cn.org.landcloud.survey.util.CloseUtils; |
||||
|
||||
/** |
||||
* <pre> |
||||
* author: Blankj |
||||
* blog : http://blankj.com
|
||||
* time : 2017/06/22 |
||||
* desc : 文件读写相关工具类 |
||||
* </pre> |
||||
*/ |
||||
public final class FileIOUtils { |
||||
|
||||
private FileIOUtils() { |
||||
throw new UnsupportedOperationException("u can't instantiate me..."); |
||||
} |
||||
|
||||
private static final String LINE_SEP = System.getProperty("line.separator"); |
||||
|
||||
private static int sBufferSize = 8192; |
||||
|
||||
/** |
||||
* 将输入流写入文件 |
||||
* |
||||
* @param filePath 路径 |
||||
* @param is 输入流 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromIS(final String filePath, final InputStream is) { |
||||
return writeFileFromIS(getFileByPath(filePath), is, false); |
||||
} |
||||
|
||||
/** |
||||
* 将输入流写入文件 |
||||
* |
||||
* @param filePath 路径 |
||||
* @param is 输入流 |
||||
* @param append 是否追加在文件末 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromIS(final String filePath, final InputStream is, final boolean append) { |
||||
return writeFileFromIS(getFileByPath(filePath), is, append); |
||||
} |
||||
|
||||
/** |
||||
* 将输入流写入文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param is 输入流 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromIS(final File file, final InputStream is) { |
||||
return writeFileFromIS(file, is, false); |
||||
} |
||||
|
||||
/** |
||||
* 将输入流写入文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param is 输入流 |
||||
* @param append 是否追加在文件末 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromIS(final File file, final InputStream is, final boolean append) { |
||||
if (!createOrExistsFile(file) || is == null) return false; |
||||
OutputStream os = null; |
||||
try { |
||||
os = new BufferedOutputStream(new FileOutputStream(file, append)); |
||||
byte data[] = new byte[sBufferSize]; |
||||
int len; |
||||
while ((len = is.read(data, 0, sBufferSize)) != -1) { |
||||
os.write(data, 0, len); |
||||
} |
||||
return true; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} finally { |
||||
CloseUtils.closeIO(is, os); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param bytes 字节数组 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByStream(final String filePath, final byte[] bytes) { |
||||
return writeFileFromBytesByStream(getFileByPath(filePath), bytes, false); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param bytes 字节数组 |
||||
* @param append 是否追加在文件末 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByStream(final String filePath, final byte[] bytes, final boolean append) { |
||||
return writeFileFromBytesByStream(getFileByPath(filePath), bytes, append); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param bytes 字节数组 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByStream(final File file, final byte[] bytes) { |
||||
return writeFileFromBytesByStream(file, bytes, false); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param bytes 字节数组 |
||||
* @param append 是否追加在文件末 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByStream(final File file, final byte[] bytes, final boolean append) { |
||||
if (bytes == null || !createOrExistsFile(file)) return false; |
||||
BufferedOutputStream bos = null; |
||||
try { |
||||
bos = new BufferedOutputStream(new FileOutputStream(file, append)); |
||||
bos.write(bytes); |
||||
return true; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} finally { |
||||
CloseUtils.closeIO(bos); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param bytes 字节数组 |
||||
* @param isForce 是否写入文件 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByChannel(final String filePath, final byte[] bytes, final boolean isForce) { |
||||
return writeFileFromBytesByChannel(getFileByPath(filePath), bytes, false, isForce); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param bytes 字节数组 |
||||
* @param append 是否追加在文件末 |
||||
* @param isForce 是否写入文件 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByChannel(final String filePath, final byte[] bytes, final boolean append, final boolean isForce) { |
||||
return writeFileFromBytesByChannel(getFileByPath(filePath), bytes, append, isForce); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param bytes 字节数组 |
||||
* @param isForce 是否写入文件 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByChannel(final File file, final byte[] bytes, final boolean isForce) { |
||||
return writeFileFromBytesByChannel(file, bytes, false, isForce); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param bytes 字节数组 |
||||
* @param append 是否追加在文件末 |
||||
* @param isForce 是否写入文件 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByChannel(final File file, final byte[] bytes, final boolean append, final boolean isForce) { |
||||
if (bytes == null) return false; |
||||
FileChannel fc = null; |
||||
try { |
||||
fc = new FileOutputStream(file, append).getChannel(); |
||||
fc.position(fc.size()); |
||||
fc.write(ByteBuffer.wrap(bytes)); |
||||
if (isForce) fc.force(true); |
||||
return true; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} finally { |
||||
CloseUtils.closeIO(fc); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param bytes 字节数组 |
||||
* @param isForce 是否写入文件 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByMap(final String filePath, final byte[] bytes, final boolean isForce) { |
||||
return writeFileFromBytesByMap(filePath, bytes, false, isForce); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param bytes 字节数组 |
||||
* @param append 是否追加在文件末 |
||||
* @param isForce 是否写入文件 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByMap(final String filePath, final byte[] bytes, final boolean append, final boolean isForce) { |
||||
return writeFileFromBytesByMap(getFileByPath(filePath), bytes, append, isForce); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param bytes 字节数组 |
||||
* @param isForce 是否写入文件 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByMap(final File file, final byte[] bytes, final boolean isForce) { |
||||
return writeFileFromBytesByMap(file, bytes, false, isForce); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组写入文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param bytes 字节数组 |
||||
* @param append 是否追加在文件末 |
||||
* @param isForce 是否写入文件 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromBytesByMap(final File file, final byte[] bytes, final boolean append, final boolean isForce) { |
||||
if (bytes == null || !createOrExistsFile(file)) return false; |
||||
FileChannel fc = null; |
||||
try { |
||||
fc = new FileOutputStream(file, append).getChannel(); |
||||
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, fc.size(), bytes.length); |
||||
mbb.put(bytes); |
||||
if (isForce) mbb.force(); |
||||
return true; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} finally { |
||||
CloseUtils.closeIO(fc); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 将字符串写入文件 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param content 写入内容 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromString(final String filePath, final String content) { |
||||
return writeFileFromString(getFileByPath(filePath), content, false); |
||||
} |
||||
|
||||
/** |
||||
* 将字符串写入文件 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param content 写入内容 |
||||
* @param append 是否追加在文件末 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromString(final String filePath, final String content, final boolean append) { |
||||
return writeFileFromString(getFileByPath(filePath), content, append); |
||||
} |
||||
|
||||
/** |
||||
* 将字符串写入文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param content 写入内容 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromString(final File file, final String content) { |
||||
return writeFileFromString(file, content, false); |
||||
} |
||||
|
||||
/** |
||||
* 将字符串写入文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param content 写入内容 |
||||
* @param append 是否追加在文件末 |
||||
* @return {@code true}: 写入成功<br>{@code false}: 写入失败 |
||||
*/ |
||||
public static boolean writeFileFromString(final File file, final String content, final boolean append) { |
||||
if (file == null || content == null) return false; |
||||
if (!createOrExistsFile(file)) return false; |
||||
BufferedWriter bw = null; |
||||
try { |
||||
bw = new BufferedWriter(new FileWriter(file, append)); |
||||
bw.write(content); |
||||
return true; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} finally { |
||||
CloseUtils.closeIO(bw); |
||||
} |
||||
} |
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// the divide line of write and read
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** |
||||
* 读取文件到字符串链表中 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @return 字符串链表中 |
||||
*/ |
||||
public static List<String> readFile2List(final String filePath) { |
||||
return readFile2List(getFileByPath(filePath), null); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串链表中 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param charsetName 编码格式 |
||||
* @return 字符串链表中 |
||||
*/ |
||||
public static List<String> readFile2List(final String filePath, final String charsetName) { |
||||
return readFile2List(getFileByPath(filePath), charsetName); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串链表中 |
||||
* |
||||
* @param file 文件 |
||||
* @return 字符串链表中 |
||||
*/ |
||||
public static List<String> readFile2List(final File file) { |
||||
return readFile2List(file, 0, 0x7FFFFFFF, null); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串链表中 |
||||
* |
||||
* @param file 文件 |
||||
* @param charsetName 编码格式 |
||||
* @return 字符串链表中 |
||||
*/ |
||||
public static List<String> readFile2List(final File file, final String charsetName) { |
||||
return readFile2List(file, 0, 0x7FFFFFFF, charsetName); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串链表中 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param st 需要读取的开始行数 |
||||
* @param end 需要读取的结束行数 |
||||
* @return 字符串链表中 |
||||
*/ |
||||
public static List<String> readFile2List(final String filePath, final int st, final int end) { |
||||
return readFile2List(getFileByPath(filePath), st, end, null); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串链表中 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param st 需要读取的开始行数 |
||||
* @param end 需要读取的结束行数 |
||||
* @param charsetName 编码格式 |
||||
* @return 字符串链表中 |
||||
*/ |
||||
public static List<String> readFile2List(final String filePath, final int st, final int end, final String charsetName) { |
||||
return readFile2List(getFileByPath(filePath), st, end, charsetName); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串链表中 |
||||
* |
||||
* @param file 文件 |
||||
* @param st 需要读取的开始行数 |
||||
* @param end 需要读取的结束行数 |
||||
* @return 字符串链表中 |
||||
*/ |
||||
public static List<String> readFile2List(final File file, final int st, final int end) { |
||||
return readFile2List(file, st, end, null); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串链表中 |
||||
* |
||||
* @param file 文件 |
||||
* @param st 需要读取的开始行数 |
||||
* @param end 需要读取的结束行数 |
||||
* @param charsetName 编码格式 |
||||
* @return 字符串链表中 |
||||
*/ |
||||
public static List<String> readFile2List(final File file, final int st, final int end, final String charsetName) { |
||||
if (!isFileExists(file)) return null; |
||||
if (st > end) return null; |
||||
BufferedReader reader = null; |
||||
try { |
||||
String line; |
||||
int curLine = 1; |
||||
List<String> list = new ArrayList<>(); |
||||
if (isSpace(charsetName)) { |
||||
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); |
||||
} else { |
||||
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName)); |
||||
} |
||||
while ((line = reader.readLine()) != null) { |
||||
if (curLine > end) break; |
||||
if (st <= curLine && curLine <= end) list.add(line); |
||||
++curLine; |
||||
} |
||||
return list; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} finally { |
||||
CloseUtils.closeIO(reader); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串中 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @return 字符串 |
||||
*/ |
||||
public static String readFile2String(final String filePath) { |
||||
return readFile2String(getFileByPath(filePath), null); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串中 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @param charsetName 编码格式 |
||||
* @return 字符串 |
||||
*/ |
||||
public static String readFile2String(final String filePath, final String charsetName) { |
||||
return readFile2String(getFileByPath(filePath), charsetName); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串中 |
||||
* |
||||
* @param file 文件 |
||||
* @return 字符串 |
||||
*/ |
||||
public static String readFile2String(final File file) { |
||||
return readFile2String(file, null); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字符串中 |
||||
* |
||||
* @param file 文件 |
||||
* @param charsetName 编码格式 |
||||
* @return 字符串 |
||||
*/ |
||||
public static String readFile2String(final File file, final String charsetName) { |
||||
if (!isFileExists(file)) return null; |
||||
BufferedReader reader = null; |
||||
try { |
||||
StringBuilder sb = new StringBuilder(); |
||||
if (isSpace(charsetName)) { |
||||
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); |
||||
} else { |
||||
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName)); |
||||
} |
||||
String line; |
||||
if ((line = reader.readLine()) != null) { |
||||
sb.append(line); |
||||
while ((line = reader.readLine()) != null) { |
||||
sb.append(LINE_SEP).append(line); |
||||
} |
||||
} |
||||
return sb.toString(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} finally { |
||||
CloseUtils.closeIO(reader); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字节数组中 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @return 字符数组 |
||||
*/ |
||||
public static byte[] readFile2BytesByStream(final String filePath) { |
||||
return readFile2BytesByStream(getFileByPath(filePath)); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字节数组中 |
||||
* |
||||
* @param file 文件 |
||||
* @return 字符数组 |
||||
*/ |
||||
public static byte[] readFile2BytesByStream(final File file) { |
||||
if (!isFileExists(file)) return null; |
||||
FileInputStream fis = null; |
||||
ByteArrayOutputStream os = null; |
||||
try { |
||||
fis = new FileInputStream(file); |
||||
os = new ByteArrayOutputStream(); |
||||
byte[] b = new byte[sBufferSize]; |
||||
int len; |
||||
while ((len = fis.read(b, 0, sBufferSize)) != -1) { |
||||
os.write(b, 0, len); |
||||
} |
||||
return os.toByteArray(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} finally { |
||||
CloseUtils.closeIO(fis, os); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字节数组中 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @return 字符数组 |
||||
*/ |
||||
public static byte[] readFile2BytesByChannel(final String filePath) { |
||||
return readFile2BytesByChannel(getFileByPath(filePath)); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字节数组中 |
||||
* |
||||
* @param file 文件 |
||||
* @return 字符数组 |
||||
*/ |
||||
public static byte[] readFile2BytesByChannel(final File file) { |
||||
if (!isFileExists(file)) return null; |
||||
FileChannel fc = null; |
||||
try { |
||||
fc = new RandomAccessFile(file, "r").getChannel(); |
||||
ByteBuffer byteBuffer = ByteBuffer.allocate((int) fc.size()); |
||||
while (true) { |
||||
if (!((fc.read(byteBuffer)) > 0)) break; |
||||
} |
||||
return byteBuffer.array(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} finally { |
||||
CloseUtils.closeIO(fc); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字节数组中 |
||||
* |
||||
* @param filePath 文件路径 |
||||
* @return 字符数组 |
||||
*/ |
||||
public static byte[] readFile2BytesByMap(final String filePath) { |
||||
return readFile2BytesByMap(getFileByPath(filePath)); |
||||
} |
||||
|
||||
/** |
||||
* 读取文件到字节数组中 |
||||
* |
||||
* @param file 文件 |
||||
* @return 字符数组 |
||||
*/ |
||||
public static byte[] readFile2BytesByMap(final File file) { |
||||
if (!isFileExists(file)) return null; |
||||
FileChannel fc = null; |
||||
try { |
||||
fc = new RandomAccessFile(file, "r").getChannel(); |
||||
int size = (int) fc.size(); |
||||
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, size).load(); |
||||
byte[] result = new byte[size]; |
||||
mbb.get(result, 0, size); |
||||
return result; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} finally { |
||||
CloseUtils.closeIO(fc); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 读取文件指定位置开始的字节数 |
||||
* |
||||
* @param file |
||||
* @param readSize |
||||
* @param offset |
||||
* @return |
||||
*/ |
||||
public static byte[] readFile2Byte(final File file, int readSize, long offset) { |
||||
|
||||
if (!isFileExists(file)) return null; |
||||
FileChannel fc = null; |
||||
try { |
||||
fc = new RandomAccessFile(file, "r").getChannel(); |
||||
int size = (int) fc.size(); |
||||
if (offset + readSize > size) return null; |
||||
|
||||
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, offset, readSize).load(); |
||||
byte[] result = new byte[readSize]; |
||||
mbb.get(result, 0, readSize); |
||||
return result; |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} finally { |
||||
CloseUtils.closeIO(fc); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 设置缓冲区尺寸 |
||||
* |
||||
* @param bufferSize 缓冲区大小 |
||||
*/ |
||||
public static void setBufferSize(final int bufferSize) { |
||||
sBufferSize = bufferSize; |
||||
} |
||||
|
||||
private static File getFileByPath(final String filePath) { |
||||
return isSpace(filePath) ? null : new File(filePath); |
||||
} |
||||
|
||||
private static boolean createOrExistsFile(final String filePath) { |
||||
return createOrExistsFile(getFileByPath(filePath)); |
||||
} |
||||
|
||||
private static boolean createOrExistsFile(final File file) { |
||||
if (file == null) return false; |
||||
if (file.exists()) return file.isFile(); |
||||
if (!createOrExistsDir(file.getParentFile())) return false; |
||||
try { |
||||
return file.createNewFile(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static boolean createOrExistsDir(final File file) { |
||||
return file != null && (file.exists() ? file.isDirectory() : file.mkdirs()); |
||||
} |
||||
|
||||
private static boolean isFileExists(final File file) { |
||||
return file != null && file.exists(); |
||||
} |
||||
|
||||
private static boolean isSpace(final String s) { |
||||
if (s == null) return true; |
||||
for (int i = 0, len = s.length(); i < len; ++i) { |
||||
if (!Character.isWhitespace(s.charAt(i))) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,43 @@ |
||||
package cn.org.landcloud.survey.util; |
||||
|
||||
import androidx.annotation.IntDef; |
||||
|
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
|
||||
/** |
||||
* <pre> |
||||
* author: Blankj |
||||
* blog : http://blankj.com
|
||||
* time : 2017/03/13 |
||||
* desc : 时间相关常量 |
||||
* </pre> |
||||
*/ |
||||
public final class TimeConstants { |
||||
|
||||
/** |
||||
* 毫秒与毫秒的倍数 |
||||
*/ |
||||
public static final int MSEC = 1; |
||||
/** |
||||
* 秒与毫秒的倍数 |
||||
*/ |
||||
public static final int SEC = 1000; |
||||
/** |
||||
* 分与毫秒的倍数 |
||||
*/ |
||||
public static final int MIN = 60000; |
||||
/** |
||||
* 时与毫秒的倍数 |
||||
*/ |
||||
public static final int HOUR = 3600000; |
||||
/** |
||||
* 天与毫秒的倍数 |
||||
*/ |
||||
public static final int DAY = 86400000; |
||||
|
||||
@IntDef({MSEC, SEC, MIN, HOUR, DAY}) |
||||
@Retention(RetentionPolicy.SOURCE) |
||||
public @interface Unit { |
||||
} |
||||
} |
@ -0,0 +1,31 @@ |
||||
package cn.org.landcloud.survey.util; |
||||
|
||||
import java.nio.charset.StandardCharsets; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
import cn.org.landcloud.security.sm2.SM2; |
||||
import cn.org.landcloud.security.sm2.SM2EncDecUtils; |
||||
import cn.org.landcloud.security.sm2.SM2SignVO; |
||||
import cn.org.landcloud.security.sm2.SM2SignVerUtils; |
||||
import cn.org.landcloud.security.sm3.SM3Utils; |
||||
|
||||
public class Utils { |
||||
|
||||
|
||||
/** |
||||
* 生成附件校验码 |
||||
* @param content |
||||
* @param privateKey |
||||
* @return |
||||
*/ |
||||
public static String makeJYM(String content,String privateKey) { |
||||
String hash = SM3Utils.sm3(content); |
||||
try { |
||||
SM2SignVO sm2SignVO = SM2SignVerUtils.Sign2SM2(Util.hexStringToBytes(privateKey),hash.getBytes(StandardCharsets.UTF_8)); |
||||
return sm2SignVO.getSm2_signForSoft(); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:aapt="http://schemas.android.com/aapt" |
||||
android:width="108dp" |
||||
android:height="108dp" |
||||
android:viewportWidth="108" |
||||
android:viewportHeight="108"> |
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> |
||||
<aapt:attr name="android:fillColor"> |
||||
<gradient |
||||
android:endX="85.84757" |
||||
android:endY="92.4963" |
||||
android:startX="42.9492" |
||||
android:startY="49.59793" |
||||
android:type="linear"> |
||||
<item |
||||
android:color="#44000000" |
||||
android:offset="0.0" /> |
||||
<item |
||||
android:color="#00000000" |
||||
android:offset="1.0" /> |
||||
</gradient> |
||||
</aapt:attr> |
||||
</path> |
||||
<path |
||||
android:fillColor="#FFFFFF" |
||||
android:fillType="nonZero" |
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" |
||||
android:strokeWidth="1" |
||||
android:strokeColor="#00000000" /> |
||||
</vector> |
@ -0,0 +1,170 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="108dp" |
||||
android:height="108dp" |
||||
android:viewportWidth="108" |
||||
android:viewportHeight="108"> |
||||
<path |
||||
android:fillColor="#3DDC84" |
||||
android:pathData="M0,0h108v108h-108z" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M9,0L9,108" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M19,0L19,108" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M29,0L29,108" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M39,0L39,108" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M49,0L49,108" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M59,0L59,108" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M69,0L69,108" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M79,0L79,108" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M89,0L89,108" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M99,0L99,108" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M0,9L108,9" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M0,19L108,19" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M0,29L108,29" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M0,39L108,39" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M0,49L108,49" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M0,59L108,59" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M0,69L108,69" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M0,79L108,79" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M0,89L108,89" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M0,99L108,99" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M19,29L89,29" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M19,39L89,39" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M19,49L89,49" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M19,59L89,59" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M19,69L89,69" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M19,79L89,79" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M29,19L29,89" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M39,19L39,89" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M49,19L49,89" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M59,19L59,89" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M69,19L69,89" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
<path |
||||
android:fillColor="#00000000" |
||||
android:pathData="M79,19L79,89" |
||||
android:strokeWidth="0.8" |
||||
android:strokeColor="#33FFFFFF" /> |
||||
</vector> |
@ -0,0 +1,71 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
tools:context=".MainActivity"> |
||||
|
||||
<Button |
||||
android:id="@+id/create_ssl_btn" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
app:layout_constraintEnd_toEndOf="parent" |
||||
app:layout_constraintStart_toStartOf="parent" |
||||
app:layout_constraintTop_toTopOf="parent" |
||||
android:text="创建公私钥" |
||||
android:onClick="createSSL" |
||||
tools:ignore="UsingOnClickInXml" /> |
||||
|
||||
|
||||
|
||||
<Button |
||||
android:id="@+id/create_hash_btn" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
app:layout_constraintEnd_toEndOf="parent" |
||||
app:layout_constraintStart_toStartOf="parent" |
||||
app:layout_constraintTop_toBottomOf="@+id/create_ssl_btn" |
||||
android:text="生成附件hash" |
||||
android:onClick="getHash"/> |
||||
|
||||
<Button |
||||
android:id="@+id/create_jym_btn" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
app:layout_constraintEnd_toEndOf="parent" |
||||
app:layout_constraintStart_toStartOf="parent" |
||||
app:layout_constraintTop_toBottomOf="@+id/create_hash_btn" |
||||
android:text="生成附件信息签名" |
||||
android:onClick="getJYM"/> |
||||
|
||||
<Button |
||||
android:id="@+id/init_data_btn" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
app:layout_constraintEnd_toEndOf="parent" |
||||
app:layout_constraintStart_toStartOf="parent" |
||||
app:layout_constraintTop_toBottomOf="@+id/create_jym_btn" |
||||
android:text="生成样例成果db包" |
||||
android:onClick="initData"/> |
||||
|
||||
<ScrollView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="0dp" |
||||
android:scrollbars="vertical" |
||||
app:layout_constraintBottom_toBottomOf="parent" |
||||
app:layout_constraintEnd_toEndOf="parent" |
||||
app:layout_constraintStart_toStartOf="parent" |
||||
app:layout_constraintTop_toBottomOf="@+id/init_data_btn" > |
||||
<TextView |
||||
android:id="@+id/log_tv" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:hint="输出日志" |
||||
android:scrollbars="vertical" |
||||
android:singleLine="false" /> |
||||
</ScrollView> |
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout> |
@ -0,0 +1,5 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<background android:drawable="@drawable/ic_launcher_background" /> |
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" /> |
||||
</adaptive-icon> |
@ -0,0 +1,5 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<background android:drawable="@drawable/ic_launcher_background" /> |
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" /> |
||||
</adaptive-icon> |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 982 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 7.6 KiB |
@ -0,0 +1,16 @@ |
||||
<resources xmlns:tools="http://schemas.android.com/tools"> |
||||
<!-- Base application theme. --> |
||||
<style name="Theme.Landsurvey" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> |
||||
<!-- Primary brand color. --> |
||||
<item name="colorPrimary">@color/purple_200</item> |
||||
<item name="colorPrimaryVariant">@color/purple_700</item> |
||||
<item name="colorOnPrimary">@color/black</item> |
||||
<!-- Secondary brand color. --> |
||||
<item name="colorSecondary">@color/teal_200</item> |
||||
<item name="colorSecondaryVariant">@color/teal_200</item> |
||||
<item name="colorOnSecondary">@color/black</item> |
||||
<!-- Status bar color. --> |
||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item> |
||||
<!-- Customize your theme here. --> |
||||
</style> |
||||
</resources> |
@ -0,0 +1,10 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<color name="purple_200">#FFBB86FC</color> |
||||
<color name="purple_500">#FF6200EE</color> |
||||
<color name="purple_700">#FF3700B3</color> |
||||
<color name="teal_200">#FF03DAC5</color> |
||||
<color name="teal_700">#FF018786</color> |
||||
<color name="black">#FF000000</color> |
||||
<color name="white">#FFFFFFFF</color> |
||||
</resources> |
@ -0,0 +1,3 @@ |
||||
<resources> |
||||
<string name="app_name">举证数据接口样例</string> |
||||
</resources> |
@ -0,0 +1,16 @@ |
||||
<resources xmlns:tools="http://schemas.android.com/tools"> |
||||
<!-- Base application theme. --> |
||||
<style name="Theme.Landsurvey" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> |
||||
<!-- Primary brand color. --> |
||||
<item name="colorPrimary">@color/purple_500</item> |
||||
<item name="colorPrimaryVariant">@color/purple_700</item> |
||||
<item name="colorOnPrimary">@color/white</item> |
||||
<!-- Secondary brand color. --> |
||||
<item name="colorSecondary">@color/teal_200</item> |
||||
<item name="colorSecondaryVariant">@color/teal_700</item> |
||||
<item name="colorOnSecondary">@color/black</item> |
||||
<!-- Status bar color. --> |
||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item> |
||||
<!-- Customize your theme here. --> |
||||
</style> |
||||
</resources> |
@ -0,0 +1,13 @@ |
||||
<?xml version="1.0" encoding="utf-8"?><!-- |
||||
Sample backup rules file; uncomment and customize as necessary. |
||||
See https://developer.android.com/guide/topics/data/autobackup |
||||
for details. |
||||
Note: This file is ignored for devices older that API 31 |
||||
See https://developer.android.com/about/versions/12/backup-restore |
||||
--> |
||||
<full-backup-content> |
||||
<!-- |
||||
<include domain="sharedpref" path="."/> |
||||
<exclude domain="sharedpref" path="device.xml"/> |
||||
--> |
||||
</full-backup-content> |
@ -0,0 +1,19 @@ |
||||
<?xml version="1.0" encoding="utf-8"?><!-- |
||||
Sample data extraction rules file; uncomment and customize as necessary. |
||||
See https://developer.android.com/about/versions/12/backup-restore#xml-changes |
||||
for details. |
||||
--> |
||||
<data-extraction-rules> |
||||
<cloud-backup> |
||||
<!-- TODO: Use <include> and <exclude> to control what is backed up. |
||||
<include .../> |
||||
<exclude .../> |
||||
--> |
||||
</cloud-backup> |
||||
<!-- |
||||
<device-transfer> |
||||
<include .../> |
||||
<exclude .../> |
||||
</device-transfer> |
||||
--> |
||||
</data-extraction-rules> |
@ -0,0 +1,17 @@ |
||||
package cn.org.landcloud.survey; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import static org.junit.Assert.*; |
||||
|
||||
/** |
||||
* Example local unit test, which will execute on the development machine (host). |
||||
* |
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a> |
||||
*/ |
||||
public class ExampleUnitTest { |
||||
@Test |
||||
public void addition_isCorrect() { |
||||
assertEquals(4, 2 + 2); |
||||
} |
||||
} |
@ -0,0 +1,5 @@ |
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules. |
||||
plugins { |
||||
id 'com.android.application' version '7.3.0' apply false |
||||
id 'com.android.library' version '7.3.0' apply false |
||||
} |
@ -0,0 +1,21 @@ |
||||
# Project-wide Gradle settings. |
||||
# IDE (e.g. Android Studio) users: |
||||
# Gradle settings configured through the IDE *will override* |
||||
# any settings specified in this file. |
||||
# For more details on how to configure your build environment visit |
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html |
||||
# Specifies the JVM arguments used for the daemon process. |
||||
# The setting is particularly useful for tweaking memory settings. |
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 |
||||
# When configured, Gradle will run in incubating parallel mode. |
||||
# This option should only be used with decoupled projects. More details, visit |
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects |
||||
# org.gradle.parallel=true |
||||
# AndroidX package structure to make it clearer which packages are bundled with the |
||||
# Android operating system, and which are packaged with your app's APK |
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn |
||||
android.useAndroidX=true |
||||
# Enables namespacing of each library's R class so that its R class includes only the |
||||
# resources declared in the library itself and none from the library's dependencies, |
||||
# thereby reducing the size of the R class for that library |
||||
android.nonTransitiveRClass=true |
@ -0,0 +1,6 @@ |
||||
#Wed Oct 12 10:45:05 CST 2022 |
||||
distributionBase=GRADLE_USER_HOME |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip |
||||
distributionPath=wrapper/dists |
||||
zipStorePath=wrapper/dists |
||||
zipStoreBase=GRADLE_USER_HOME |
@ -0,0 +1,185 @@ |
||||
#!/usr/bin/env sh |
||||
|
||||
# |
||||
# Copyright 2015 the original author or authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# https://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
# |
||||
|
||||
############################################################################## |
||||
## |
||||
## Gradle start up script for UN*X |
||||
## |
||||
############################################################################## |
||||
|
||||
# Attempt to set APP_HOME |
||||
# Resolve links: $0 may be a link |
||||
PRG="$0" |
||||
# Need this for relative symlinks. |
||||
while [ -h "$PRG" ] ; do |
||||
ls=`ls -ld "$PRG"` |
||||
link=`expr "$ls" : '.*-> \(.*\)$'` |
||||
if expr "$link" : '/.*' > /dev/null; then |
||||
PRG="$link" |
||||
else |
||||
PRG=`dirname "$PRG"`"/$link" |
||||
fi |
||||
done |
||||
SAVED="`pwd`" |
||||
cd "`dirname \"$PRG\"`/" >/dev/null |
||||
APP_HOME="`pwd -P`" |
||||
cd "$SAVED" >/dev/null |
||||
|
||||
APP_NAME="Gradle" |
||||
APP_BASE_NAME=`basename "$0"` |
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' |
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value. |
||||
MAX_FD="maximum" |
||||
|
||||
warn () { |
||||
echo "$*" |
||||
} |
||||
|
||||
die () { |
||||
echo |
||||
echo "$*" |
||||
echo |
||||
exit 1 |
||||
} |
||||
|
||||
# OS specific support (must be 'true' or 'false'). |
||||
cygwin=false |
||||
msys=false |
||||
darwin=false |
||||
nonstop=false |
||||
case "`uname`" in |
||||
CYGWIN* ) |
||||
cygwin=true |
||||
;; |
||||
Darwin* ) |
||||
darwin=true |
||||
;; |
||||
MINGW* ) |
||||
msys=true |
||||
;; |
||||
NONSTOP* ) |
||||
nonstop=true |
||||
;; |
||||
esac |
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar |
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM. |
||||
if [ -n "$JAVA_HOME" ] ; then |
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then |
||||
# IBM's JDK on AIX uses strange locations for the executables |
||||
JAVACMD="$JAVA_HOME/jre/sh/java" |
||||
else |
||||
JAVACMD="$JAVA_HOME/bin/java" |
||||
fi |
||||
if [ ! -x "$JAVACMD" ] ; then |
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME |
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the |
||||
location of your Java installation." |
||||
fi |
||||
else |
||||
JAVACMD="java" |
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the |
||||
location of your Java installation." |
||||
fi |
||||
|
||||
# Increase the maximum file descriptors if we can. |
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then |
||||
MAX_FD_LIMIT=`ulimit -H -n` |
||||
if [ $? -eq 0 ] ; then |
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then |
||||
MAX_FD="$MAX_FD_LIMIT" |
||||
fi |
||||
ulimit -n $MAX_FD |
||||
if [ $? -ne 0 ] ; then |
||||
warn "Could not set maximum file descriptor limit: $MAX_FD" |
||||
fi |
||||
else |
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" |
||||
fi |
||||
fi |
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock |
||||
if $darwin; then |
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" |
||||
fi |
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java |
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then |
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"` |
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` |
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"` |
||||
|
||||
# We build the pattern for arguments to be converted via cygpath |
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` |
||||
SEP="" |
||||
for dir in $ROOTDIRSRAW ; do |
||||
ROOTDIRS="$ROOTDIRS$SEP$dir" |
||||
SEP="|" |
||||
done |
||||
OURCYGPATTERN="(^($ROOTDIRS))" |
||||
# Add a user-defined pattern to the cygpath arguments |
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then |
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" |
||||
fi |
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh |
||||
i=0 |
||||
for arg in "$@" ; do |
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` |
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option |
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition |
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` |
||||
else |
||||
eval `echo args$i`="\"$arg\"" |
||||
fi |
||||
i=`expr $i + 1` |
||||
done |
||||
case $i in |
||||
0) set -- ;; |
||||
1) set -- "$args0" ;; |
||||
2) set -- "$args0" "$args1" ;; |
||||
3) set -- "$args0" "$args1" "$args2" ;; |
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;; |
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; |
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; |
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; |
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; |
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; |
||||
esac |
||||
fi |
||||
|
||||
# Escape application args |
||||
save () { |
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done |
||||
echo " " |
||||
} |
||||
APP_ARGS=`save "$@"` |
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules |
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" |
||||
|
||||
exec "$JAVACMD" "$@" |
@ -0,0 +1,89 @@ |
||||
@rem |
||||
@rem Copyright 2015 the original author or authors. |
||||
@rem |
||||
@rem Licensed under the Apache License, Version 2.0 (the "License"); |
||||
@rem you may not use this file except in compliance with the License. |
||||
@rem You may obtain a copy of the License at |
||||
@rem |
||||
@rem https://www.apache.org/licenses/LICENSE-2.0 |
||||
@rem |
||||
@rem Unless required by applicable law or agreed to in writing, software |
||||
@rem distributed under the License is distributed on an "AS IS" BASIS, |
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
@rem See the License for the specific language governing permissions and |
||||
@rem limitations under the License. |
||||
@rem |
||||
|
||||
@if "%DEBUG%" == "" @echo off |
||||
@rem ########################################################################## |
||||
@rem |
||||
@rem Gradle startup script for Windows |
||||
@rem |
||||
@rem ########################################################################## |
||||
|
||||
@rem Set local scope for the variables with windows NT shell |
||||
if "%OS%"=="Windows_NT" setlocal |
||||
|
||||
set DIRNAME=%~dp0 |
||||
if "%DIRNAME%" == "" set DIRNAME=. |
||||
set APP_BASE_NAME=%~n0 |
||||
set APP_HOME=%DIRNAME% |
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter. |
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi |
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" |
||||
|
||||
@rem Find java.exe |
||||
if defined JAVA_HOME goto findJavaFromJavaHome |
||||
|
||||
set JAVA_EXE=java.exe |
||||
%JAVA_EXE% -version >NUL 2>&1 |
||||
if "%ERRORLEVEL%" == "0" goto execute |
||||
|
||||
echo. |
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |
||||
echo. |
||||
echo Please set the JAVA_HOME variable in your environment to match the |
||||
echo location of your Java installation. |
||||
|
||||
goto fail |
||||
|
||||
:findJavaFromJavaHome |
||||
set JAVA_HOME=%JAVA_HOME:"=% |
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe |
||||
|
||||
if exist "%JAVA_EXE%" goto execute |
||||
|
||||
echo. |
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% |
||||
echo. |
||||
echo Please set the JAVA_HOME variable in your environment to match the |
||||
echo location of your Java installation. |
||||
|
||||
goto fail |
||||
|
||||
:execute |
||||
@rem Setup the command line |
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar |
||||
|
||||
|
||||
@rem Execute Gradle |
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* |
||||
|
||||
:end |
||||
@rem End local scope for the variables with windows NT shell |
||||
if "%ERRORLEVEL%"=="0" goto mainEnd |
||||
|
||||
:fail |
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of |
||||
rem the _cmd.exe /c_ return code! |
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 |
||||
exit /b 1 |
||||
|
||||
:mainEnd |
||||
if "%OS%"=="Windows_NT" endlocal |
||||
|
||||
:omega |
@ -0,0 +1,17 @@ |
||||
pluginManagement { |
||||
repositories { |
||||
gradlePluginPortal() |
||||
google() |
||||
mavenCentral() |
||||
} |
||||
} |
||||
dependencyResolutionManagement { |
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) |
||||
repositories { |
||||
google() |
||||
mavenCentral() |
||||
} |
||||
} |
||||
rootProject.name = "landsurvey" |
||||
include ':app' |
||||
include ':ssl' |
@ -0,0 +1 @@ |
||||
/build |
@ -0,0 +1,21 @@ |
||||
plugins { |
||||
id 'java-library' |
||||
} |
||||
|
||||
java { |
||||
sourceCompatibility = JavaVersion.VERSION_1_7 |
||||
targetCompatibility = JavaVersion.VERSION_1_7 |
||||
|
||||
/* task makeJar(type: jar) { |
||||
delete 'ssl.jar' |
||||
from file('src/main/java/') |
||||
destinationDir = file('build/libs') |
||||
archiveName = 'ssl.jar' |
||||
} |
||||
makeJar.dependsOn(build)*/ |
||||
} |
||||
|
||||
dependencies { |
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.63' |
||||
compileOnly 'junit:junit:4.13.2' |
||||
} |
@ -0,0 +1,128 @@ |
||||
package cn.org.landcloud.security; |
||||
|
||||
//
|
||||
// Source code recreated from a .class file by IntelliJ IDEA
|
||||
// (powered by Fernflower decompiler)
|
||||
//
|
||||
|
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.OutputStream; |
||||
|
||||
public class Base64 { |
||||
static final char[] charTab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); |
||||
|
||||
public Base64() { |
||||
} |
||||
|
||||
public static String encode(byte[] data) { |
||||
return encode(data, 0, data.length, (StringBuffer) null).toString(); |
||||
} |
||||
|
||||
public static StringBuffer encode(byte[] data, int start, int len, StringBuffer buf) { |
||||
if (null == data || data.length == 0) { |
||||
return new StringBuffer(); |
||||
} |
||||
|
||||
if (buf == null) { |
||||
buf = new StringBuffer(data.length * 3 / 2); |
||||
} |
||||
|
||||
int end = len - 3; |
||||
int i = start; |
||||
int n = 0; |
||||
|
||||
int d; |
||||
while (i <= end) { |
||||
d = (data[i] & 255) << 16 | (data[i + 1] & 255) << 8 | data[i + 2] & 255; |
||||
buf.append(charTab[d >> 18 & 63]); |
||||
buf.append(charTab[d >> 12 & 63]); |
||||
buf.append(charTab[d >> 6 & 63]); |
||||
buf.append(charTab[d & 63]); |
||||
i += 3; |
||||
if (n++ >= 14) { |
||||
n = 0; |
||||
buf.append("\r\n"); |
||||
} |
||||
} |
||||
|
||||
if (i == start + len - 2) { |
||||
d = (data[i] & 255) << 16 | (data[i + 1] & 255) << 8; |
||||
buf.append(charTab[d >> 18 & 63]); |
||||
buf.append(charTab[d >> 12 & 63]); |
||||
buf.append(charTab[d >> 6 & 63]); |
||||
buf.append("="); |
||||
} else if (i == start + len - 1) { |
||||
d = (data[i] & 255) << 16; |
||||
buf.append(charTab[d >> 18 & 63]); |
||||
buf.append(charTab[d >> 12 & 63]); |
||||
buf.append("=="); |
||||
} |
||||
|
||||
return buf; |
||||
} |
||||
|
||||
static int decode(char c) { |
||||
if (c >= 65 && c <= 90) { |
||||
return c - 65; |
||||
} else if (c >= 97 && c <= 122) { |
||||
return c - 97 + 26; |
||||
} else if (c >= 48 && c <= 57) { |
||||
return c - 48 + 26 + 26; |
||||
} else { |
||||
switch (c) { |
||||
case '+': |
||||
return 62; |
||||
case '/': |
||||
return 63; |
||||
case '=': |
||||
return 0; |
||||
default: |
||||
throw new RuntimeException("unexpected code: " + c); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static byte[] decode(String s) { |
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
||||
|
||||
try { |
||||
decode(s, bos); |
||||
} catch (IOException var3) { |
||||
throw new RuntimeException(); |
||||
} |
||||
|
||||
return bos.toByteArray(); |
||||
} |
||||
|
||||
public static void decode(String s, OutputStream os) throws IOException { |
||||
int i = 0; |
||||
int len = s.length(); |
||||
|
||||
while (true) { |
||||
while (i < len && s.charAt(i) <= 32) { |
||||
++i; |
||||
} |
||||
|
||||
if (i == len) { |
||||
break; |
||||
} |
||||
|
||||
int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + decode(s.charAt(i + 3)); |
||||
os.write(tri >> 16 & 255); |
||||
if (s.charAt(i + 2) == 61) { |
||||
break; |
||||
} |
||||
|
||||
os.write(tri >> 8 & 255); |
||||
if (s.charAt(i + 3) == 61) { |
||||
break; |
||||
} |
||||
|
||||
os.write(tri & 255); |
||||
i += 4; |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
@ -0,0 +1,617 @@ |
||||
package cn.org.landcloud.security; |
||||
|
||||
import java.math.BigInteger; |
||||
|
||||
public class Util { |
||||
/** |
||||
* 整形转换成网络传输的字节流(字节数组)型数据 |
||||
* |
||||
* @param num 一个整型数据 |
||||
* @return 4个字节的自己数组 |
||||
*/ |
||||
public static byte[] intToBytes(int num) { |
||||
byte[] bytes = new byte[4]; |
||||
bytes[0] = (byte) (0xff & (num >> 0)); |
||||
bytes[1] = (byte) (0xff & (num >> 8)); |
||||
bytes[2] = (byte) (0xff & (num >> 16)); |
||||
bytes[3] = (byte) (0xff & (num >> 24)); |
||||
return bytes; |
||||
} |
||||
|
||||
/** |
||||
* 四个字节的字节数据转换成一个整形数据 |
||||
* |
||||
* @param bytes 4个字节的字节数组 |
||||
* @return 一个整型数据 |
||||
*/ |
||||
public static int byteToInt(byte[] bytes) { |
||||
int num = 0; |
||||
int temp; |
||||
temp = (0x000000ff & (bytes[0])) << 0; |
||||
num = num | temp; |
||||
temp = (0x000000ff & (bytes[1])) << 8; |
||||
num = num | temp; |
||||
temp = (0x000000ff & (bytes[2])) << 16; |
||||
num = num | temp; |
||||
temp = (0x000000ff & (bytes[3])) << 24; |
||||
num = num | temp; |
||||
return num; |
||||
} |
||||
|
||||
/** |
||||
* 长整形转换成网络传输的字节流(字节数组)型数据 |
||||
* |
||||
* @param num 一个长整型数据 |
||||
* @return 4个字节的自己数组 |
||||
*/ |
||||
public static byte[] longToBytes(long num) { |
||||
byte[] bytes = new byte[8]; |
||||
for (int i = 0; i < 8; i++) { |
||||
bytes[i] = (byte) (0xff & (num >> (i * 8))); |
||||
} |
||||
|
||||
return bytes; |
||||
} |
||||
|
||||
/** |
||||
* 大数字转换字节流(字节数组)型数据 |
||||
* |
||||
* @param n |
||||
* @return |
||||
*/ |
||||
public static byte[] byteConvert32Bytes(BigInteger n) { |
||||
byte tmpd[] = (byte[]) null; |
||||
if (n == null) { |
||||
return null; |
||||
} |
||||
|
||||
if (n.toByteArray().length == 33) { |
||||
tmpd = new byte[32]; |
||||
System.arraycopy(n.toByteArray(), 1, tmpd, 0, 32); |
||||
} else if (n.toByteArray().length == 32) { |
||||
tmpd = n.toByteArray(); |
||||
} else { |
||||
tmpd = new byte[32]; |
||||
for (int i = 0; i < 32 - n.toByteArray().length; i++) { |
||||
tmpd[i] = 0; |
||||
} |
||||
System.arraycopy(n.toByteArray(), 0, tmpd, 32 - n.toByteArray().length, n.toByteArray().length); |
||||
} |
||||
return tmpd; |
||||
} |
||||
|
||||
/** |
||||
* 换字节流(字节数组)型数据转大数字 |
||||
* |
||||
* @param b |
||||
* @return |
||||
*/ |
||||
public static BigInteger byteConvertInteger(byte[] b) { |
||||
if (b[0] < 0) { |
||||
byte[] temp = new byte[b.length + 1]; |
||||
temp[0] = 0; |
||||
System.arraycopy(b, 0, temp, 1, b.length); |
||||
return new BigInteger(temp); |
||||
} |
||||
return new BigInteger(b); |
||||
} |
||||
|
||||
/** |
||||
* 根据字节数组获得值(十六进制数字) |
||||
* |
||||
* @param bytes |
||||
* @return |
||||
*/ |
||||
public static String getHexString(byte[] bytes) { |
||||
return getHexString(bytes, true); |
||||
} |
||||
|
||||
/** |
||||
* 根据字节数组获得值(十六进制数字) |
||||
* |
||||
* @param bytes |
||||
* @param upperCase |
||||
* @return |
||||
*/ |
||||
public static String getHexString(byte[] bytes, boolean upperCase) { |
||||
String ret = ""; |
||||
for (int i = 0; i < bytes.length; i++) { |
||||
ret += Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1); |
||||
} |
||||
return upperCase ? ret.toUpperCase() : ret; |
||||
} |
||||
|
||||
/** |
||||
* 打印十六进制字符串 |
||||
* |
||||
* @param bytes |
||||
*/ |
||||
public static void printHexString(byte[] bytes) { |
||||
for (int i = 0; i < bytes.length; i++) { |
||||
String hex = Integer.toHexString(bytes[i] & 0xFF); |
||||
if (hex.length() == 1) { |
||||
hex = '0' + hex; |
||||
} |
||||
System.out.print("0x" + hex.toUpperCase() + ","); |
||||
} |
||||
System.out.println(""); |
||||
} |
||||
|
||||
/** |
||||
* Convert hex string to byte[] |
||||
* |
||||
* @param hexString the hex string |
||||
* @return byte[] |
||||
*/ |
||||
public static byte[] hexStringToBytes(String hexString) { |
||||
if (hexString == null || hexString.equals("")) { |
||||
return null; |
||||
} |
||||
|
||||
hexString = hexString.toUpperCase(); |
||||
int length = hexString.length() / 2; |
||||
char[] hexChars = hexString.toCharArray(); |
||||
byte[] d = new byte[length]; |
||||
for (int i = 0; i < length; i++) { |
||||
int pos = i * 2; |
||||
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); |
||||
} |
||||
return d; |
||||
} |
||||
|
||||
/** |
||||
* Convert char to byte |
||||
* |
||||
* @param c char |
||||
* @return byte |
||||
*/ |
||||
public static byte charToByte(char c) { |
||||
return (byte) "0123456789ABCDEF".indexOf(c); |
||||
} |
||||
|
||||
/** |
||||
* 用于建立十六进制字符的输出的小写字符数组 |
||||
*/ |
||||
private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', |
||||
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; |
||||
|
||||
/** |
||||
* 用于建立十六进制字符的输出的大写字符数组 |
||||
*/ |
||||
private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5', |
||||
'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; |
||||
|
||||
/** |
||||
* 将字节数组转换为十六进制字符数组 |
||||
* |
||||
* @param data byte[] |
||||
* @return 十六进制char[] |
||||
*/ |
||||
public static char[] encodeHex(byte[] data) { |
||||
return encodeHex(data, true); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组转换为十六进制字符数组 |
||||
* |
||||
* @param data byte[] |
||||
* @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式 |
||||
* @return 十六进制char[] |
||||
*/ |
||||
public static char[] encodeHex(byte[] data, boolean toLowerCase) { |
||||
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组转换为十六进制字符数组 |
||||
* |
||||
* @param data byte[] |
||||
* @param toDigits 用于控制输出的char[] |
||||
* @return 十六进制char[] |
||||
*/ |
||||
protected static char[] encodeHex(byte[] data, char[] toDigits) { |
||||
int l = data.length; |
||||
char[] out = new char[l << 1]; |
||||
// two characters form the hex value.
|
||||
for (int i = 0, j = 0; i < l; i++) { |
||||
out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; |
||||
out[j++] = toDigits[0x0F & data[i]]; |
||||
} |
||||
return out; |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组转换为十六进制字符串 |
||||
* |
||||
* @param data byte[] |
||||
* @return 十六进制String |
||||
*/ |
||||
public static String encodeHexString(byte[] data) { |
||||
return encodeHexString(data, true); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组转换为十六进制字符串 |
||||
* |
||||
* @param data byte[] |
||||
* @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式 |
||||
* @return 十六进制String |
||||
*/ |
||||
public static String encodeHexString(byte[] data, boolean toLowerCase) { |
||||
return encodeHexString(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); |
||||
} |
||||
|
||||
/** |
||||
* 将字节数组转换为十六进制字符串 |
||||
* |
||||
* @param data byte[] |
||||
* @param toDigits 用于控制输出的char[] |
||||
* @return 十六进制String |
||||
*/ |
||||
protected static String encodeHexString(byte[] data, char[] toDigits) { |
||||
return new String(encodeHex(data, toDigits)); |
||||
} |
||||
|
||||
/** |
||||
* 将十六进制字符数组转换为字节数组 |
||||
* |
||||
* @param data 十六进制char[] |
||||
* @return byte[] |
||||
* @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常 |
||||
*/ |
||||
public static byte[] decodeHex(char[] data) { |
||||
int len = data.length; |
||||
|
||||
if ((len & 0x01) != 0) { |
||||
throw new RuntimeException("Odd number of characters."); |
||||
} |
||||
|
||||
byte[] out = new byte[len >> 1]; |
||||
|
||||
// two characters form the hex value.
|
||||
for (int i = 0, j = 0; j < len; i++) { |
||||
int f = toDigit(data[j], j) << 4; |
||||
j++; |
||||
f = f | toDigit(data[j], j); |
||||
j++; |
||||
out[i] = (byte) (f & 0xFF); |
||||
} |
||||
|
||||
return out; |
||||
} |
||||
|
||||
/** |
||||
* 将十六进制字符转换成一个整数 |
||||
* |
||||
* @param ch 十六进制char |
||||
* @param index 十六进制字符在字符数组中的位置 |
||||
* @return 一个整数 |
||||
* @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常 |
||||
*/ |
||||
protected static int toDigit(char ch, int index) { |
||||
int digit = Character.digit(ch, 16); |
||||
if (digit == -1) { |
||||
throw new RuntimeException("Illegal hexadecimal character " + ch |
||||
+ " at index " + index); |
||||
} |
||||
return digit; |
||||
} |
||||
|
||||
/** |
||||
* 数字字符串转ASCII码字符串 |
||||
* |
||||
* @param String 字符串 |
||||
* @return ASCII字符串 |
||||
*/ |
||||
public static String StringToAsciiString(String content) { |
||||
String result = ""; |
||||
int max = content.length(); |
||||
for (int i = 0; i < max; i++) { |
||||
char c = content.charAt(i); |
||||
String b = Integer.toHexString(c); |
||||
result = result + b; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* 十六进制转字符串 |
||||
* |
||||
* @param hexString 十六进制字符串 |
||||
* @param encodeType 编码类型4:Unicode,2:普通编码 |
||||
* @return 字符串 |
||||
*/ |
||||
public static String hexStringToString(String hexString, int encodeType) { |
||||
String result = ""; |
||||
int max = hexString.length() / encodeType; |
||||
for (int i = 0; i < max; i++) { |
||||
char c = (char) hexStringToAlgorism(hexString |
||||
.substring(i * encodeType, (i + 1) * encodeType)); |
||||
result += c; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* 十六进制字符串装十进制 |
||||
* |
||||
* @param hex 十六进制字符串 |
||||
* @return 十进制数值 |
||||
*/ |
||||
public static int hexStringToAlgorism(String hex) { |
||||
hex = hex.toUpperCase(); |
||||
int max = hex.length(); |
||||
int result = 0; |
||||
for (int i = max; i > 0; i--) { |
||||
char c = hex.charAt(i - 1); |
||||
int algorism = 0; |
||||
if (c >= '0' && c <= '9') { |
||||
algorism = c - '0'; |
||||
} else { |
||||
algorism = c - 55; |
||||
} |
||||
result += Math.pow(16, max - i) * algorism; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* 十六转二进制 |
||||
* |
||||
* @param hex 十六进制字符串 |
||||
* @return 二进制字符串 |
||||
*/ |
||||
public static String hexStringToBinary(String hex) { |
||||
hex = hex.toUpperCase(); |
||||
String result = ""; |
||||
int max = hex.length(); |
||||
for (int i = 0; i < max; i++) { |
||||
char c = hex.charAt(i); |
||||
switch (c) { |
||||
case '0': |
||||
result += "0000"; |
||||
break; |
||||
case '1': |
||||
result += "0001"; |
||||
break; |
||||
case '2': |
||||
result += "0010"; |
||||
break; |
||||
case '3': |
||||
result += "0011"; |
||||
break; |
||||
case '4': |
||||
result += "0100"; |
||||
break; |
||||
case '5': |
||||
result += "0101"; |
||||
break; |
||||
case '6': |
||||
result += "0110"; |
||||
break; |
||||
case '7': |
||||
result += "0111"; |
||||
break; |
||||
case '8': |
||||
result += "1000"; |
||||
break; |
||||
case '9': |
||||
result += "1001"; |
||||
break; |
||||
case 'A': |
||||
result += "1010"; |
||||
break; |
||||
case 'B': |
||||
result += "1011"; |
||||
break; |
||||
case 'C': |
||||
result += "1100"; |
||||
break; |
||||
case 'D': |
||||
result += "1101"; |
||||
break; |
||||
case 'E': |
||||
result += "1110"; |
||||
break; |
||||
case 'F': |
||||
result += "1111"; |
||||
break; |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* ASCII码字符串转数字字符串 |
||||
* |
||||
* @param String ASCII字符串 |
||||
* @return 字符串 |
||||
*/ |
||||
public static String AsciiStringToString(String content) { |
||||
String result = ""; |
||||
int length = content.length() / 2; |
||||
for (int i = 0; i < length; i++) { |
||||
String c = content.substring(i * 2, i * 2 + 2); |
||||
int a = hexStringToAlgorism(c); |
||||
char b = (char) a; |
||||
String d = String.valueOf(b); |
||||
result += d; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* 将十进制转换为指定长度的十六进制字符串 |
||||
* |
||||
* @param algorism int 十进制数字 |
||||
* @param maxLength int 转换后的十六进制字符串长度 |
||||
* @return String 转换后的十六进制字符串 |
||||
*/ |
||||
public static String algorismToHexString(int algorism, int maxLength) { |
||||
String result = ""; |
||||
result = Integer.toHexString(algorism); |
||||
|
||||
if (result.length() % 2 == 1) { |
||||
result = "0" + result; |
||||
} |
||||
return patchHexString(result.toUpperCase(), maxLength); |
||||
} |
||||
|
||||
/** |
||||
* 字节数组转为普通字符串(ASCII对应的字符) |
||||
* |
||||
* @param bytearray byte[] |
||||
* @return String |
||||
*/ |
||||
public static String byteToString(byte[] bytearray) { |
||||
String result = ""; |
||||
char temp; |
||||
|
||||
int length = bytearray.length; |
||||
for (int i = 0; i < length; i++) { |
||||
temp = (char) bytearray[i]; |
||||
result += temp; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* 二进制字符串转十进制 |
||||
* |
||||
* @param binary 二进制字符串 |
||||
* @return 十进制数值 |
||||
*/ |
||||
public static int binaryToAlgorism(String binary) { |
||||
int max = binary.length(); |
||||
int result = 0; |
||||
for (int i = max; i > 0; i--) { |
||||
char c = binary.charAt(i - 1); |
||||
int algorism = c - '0'; |
||||
result += Math.pow(2, max - i) * algorism; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* 十进制转换为十六进制字符串 |
||||
* |
||||
* @param algorism int 十进制的数字 |
||||
* @return String 对应的十六进制字符串 |
||||
*/ |
||||
public static String algorismToHEXString(int algorism) { |
||||
String result = ""; |
||||
result = Integer.toHexString(algorism); |
||||
|
||||
if (result.length() % 2 == 1) { |
||||
result = "0" + result; |
||||
|
||||
} |
||||
result = result.toUpperCase(); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* HEX字符串前补0,主要用于长度位数不足。 |
||||
* |
||||
* @param str String 需要补充长度的十六进制字符串 |
||||
* @param maxLength int 补充后十六进制字符串的长度 |
||||
* @return 补充结果 |
||||
*/ |
||||
static public String patchHexString(String str, int maxLength) { |
||||
String temp = ""; |
||||
for (int i = 0; i < maxLength - str.length(); i++) { |
||||
temp = "0" + temp; |
||||
} |
||||
str = (temp + str).substring(0, maxLength); |
||||
return str; |
||||
} |
||||
|
||||
/** |
||||
* 将一个字符串转换为int |
||||
* |
||||
* @param s String 要转换的字符串 |
||||
* @param defaultInt int 如果出现异常,默认返回的数字 |
||||
* @param radix int 要转换的字符串是什么进制的,如16 8 10. |
||||
* @return int 转换后的数字 |
||||
*/ |
||||
public static int parseToInt(String s, int defaultInt, int radix) { |
||||
int i = 0; |
||||
try { |
||||
i = Integer.parseInt(s, radix); |
||||
} catch (NumberFormatException ex) { |
||||
i = defaultInt; |
||||
} |
||||
return i; |
||||
} |
||||
|
||||
/** |
||||
* 将一个十进制形式的数字字符串转换为int |
||||
* |
||||
* @param s String 要转换的字符串 |
||||
* @param defaultInt int 如果出现异常,默认返回的数字 |
||||
* @return int 转换后的数字 |
||||
*/ |
||||
public static int parseToInt(String s, int defaultInt) { |
||||
int i = 0; |
||||
try { |
||||
i = Integer.parseInt(s); |
||||
} catch (NumberFormatException ex) { |
||||
i = defaultInt; |
||||
} |
||||
return i; |
||||
} |
||||
|
||||
/** |
||||
* 十六进制串转化为byte数组 |
||||
* |
||||
* @return the array of byte |
||||
*/ |
||||
public static byte[] hexToByte(String hex) |
||||
throws IllegalArgumentException { |
||||
if (hex.length() % 2 != 0) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
char[] arr = hex.toCharArray(); |
||||
byte[] b = new byte[hex.length() / 2]; |
||||
for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) { |
||||
String swap = "" + arr[i++] + arr[i]; |
||||
int byteint = Integer.parseInt(swap, 16) & 0xFF; |
||||
b[j] = new Integer(byteint).byteValue(); |
||||
} |
||||
return b; |
||||
} |
||||
|
||||
/** |
||||
* 字节数组转换为十六进制字符串 |
||||
* |
||||
* @param b byte[] 需要转换的字节数组 |
||||
* @return String 十六进制字符串 |
||||
*/ |
||||
public static String byteToHex(byte b[]) { |
||||
if (b == null) { |
||||
throw new IllegalArgumentException( |
||||
"Argument b ( byte array ) is null! "); |
||||
} |
||||
String hs = ""; |
||||
String stmp = ""; |
||||
for (int n = 0; n < b.length; n++) { |
||||
stmp = Integer.toHexString(b[n] & 0xff); |
||||
if (stmp.length() == 1) { |
||||
hs = hs + "0" + stmp; |
||||
} else { |
||||
hs = hs + stmp; |
||||
} |
||||
} |
||||
// return hs.toLowerCase();
|
||||
return hs.toUpperCase(); |
||||
} |
||||
|
||||
public static byte[] subByte(byte[] input, int startIndex, int length) { |
||||
byte[] bt = new byte[length]; |
||||
for (int i = 0; i < length; i++) { |
||||
bt[i] = input[i + startIndex]; |
||||
} |
||||
return bt; |
||||
} |
||||
} |
@ -0,0 +1,107 @@ |
||||
package cn.org.landcloud.security.sm2; |
||||
|
||||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair; |
||||
import org.bouncycastle.crypto.digests.SM3Digest; |
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters; |
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters; |
||||
import org.bouncycastle.math.ec.ECPoint; |
||||
|
||||
import java.math.BigInteger; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
|
||||
public class Cipher { |
||||
private int ct; |
||||
private ECPoint p2; |
||||
private SM3Digest sm3keybase; |
||||
private SM3Digest sm3c3; |
||||
private byte key[]; |
||||
private byte keyOff; |
||||
|
||||
public Cipher() |
||||
{ |
||||
this.ct = 1; |
||||
this.key = new byte[32]; |
||||
this.keyOff = 0; |
||||
} |
||||
|
||||
private void Reset() |
||||
{ |
||||
this.sm3keybase = new SM3Digest(); |
||||
this.sm3c3 = new SM3Digest(); |
||||
|
||||
byte p[] = Util.byteConvert32Bytes(p2.normalize().getXCoord().toBigInteger()); |
||||
this.sm3keybase.update(p, 0, p.length); |
||||
this.sm3c3.update(p, 0, p.length); |
||||
|
||||
p = Util.byteConvert32Bytes(p2.normalize().getYCoord().toBigInteger()); |
||||
this.sm3keybase.update(p, 0, p.length); |
||||
this.ct = 1; |
||||
NextKey(); |
||||
} |
||||
|
||||
private void NextKey() |
||||
{ |
||||
SM3Digest sm3keycur = new SM3Digest(this.sm3keybase); |
||||
sm3keycur.update((byte) (ct >> 24 & 0xff)); |
||||
sm3keycur.update((byte) (ct >> 16 & 0xff)); |
||||
sm3keycur.update((byte) (ct >> 8 & 0xff)); |
||||
sm3keycur.update((byte) (ct & 0xff)); |
||||
sm3keycur.doFinal(key, 0); |
||||
this.keyOff = 0; |
||||
this.ct++; |
||||
} |
||||
|
||||
public ECPoint Init_enc(SM2 sm2, ECPoint userKey) |
||||
{ |
||||
AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair(); |
||||
ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate(); |
||||
ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic(); |
||||
BigInteger k = ecpriv.getD(); |
||||
ECPoint c1 = ecpub.getQ(); |
||||
this.p2 = userKey.multiply(k); |
||||
Reset(); |
||||
return c1; |
||||
} |
||||
|
||||
public void Encrypt(byte data[]) |
||||
{ |
||||
this.sm3c3.update(data, 0, data.length); |
||||
for (int i = 0; i < data.length; i++) |
||||
{ |
||||
if (keyOff == key.length) |
||||
{ |
||||
NextKey(); |
||||
} |
||||
data[i] ^= key[keyOff++]; |
||||
} |
||||
} |
||||
|
||||
public void Init_dec(BigInteger userD, ECPoint c1) |
||||
{ |
||||
this.p2 = c1.multiply(userD); |
||||
Reset(); |
||||
} |
||||
|
||||
public void Decrypt(byte data[]) |
||||
{ |
||||
for (int i = 0; i < data.length; i++) |
||||
{ |
||||
if (keyOff == key.length) |
||||
{ |
||||
NextKey(); |
||||
} |
||||
data[i] ^= key[keyOff++]; |
||||
} |
||||
|
||||
this.sm3c3.update(data, 0, data.length); |
||||
} |
||||
|
||||
public void Dofinal(byte c3[]) |
||||
{ |
||||
byte p[] = Util.byteConvert32Bytes(p2.normalize().getYCoord().toBigInteger()); |
||||
this.sm3c3.update(p, 0, p.length); |
||||
this.sm3c3.doFinal(c3, 0); |
||||
Reset(); |
||||
} |
||||
} |
@ -0,0 +1,67 @@ |
||||
package cn.org.landcloud.security.sm2; |
||||
|
||||
import org.bouncycastle.crypto.generators.ECKeyPairGenerator; |
||||
import org.bouncycastle.crypto.params.ECDomainParameters; |
||||
import org.bouncycastle.crypto.params.ECKeyGenerationParameters; |
||||
import org.bouncycastle.math.ec.ECCurve; |
||||
import org.bouncycastle.math.ec.ECFieldElement; |
||||
import org.bouncycastle.math.ec.ECFieldElement.Fp; |
||||
import org.bouncycastle.math.ec.ECPoint; |
||||
|
||||
import java.math.BigInteger; |
||||
import java.security.SecureRandom; |
||||
|
||||
public class SM2 { |
||||
|
||||
//国密参数
|
||||
public static String[] ecc_param = { |
||||
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", |
||||
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", |
||||
"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", |
||||
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", |
||||
"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", |
||||
"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0" |
||||
}; |
||||
|
||||
public static SM2 Instance() |
||||
{ |
||||
return new SM2(); |
||||
} |
||||
|
||||
public final BigInteger ecc_p; |
||||
public final BigInteger ecc_a; |
||||
public final BigInteger ecc_b; |
||||
public final BigInteger ecc_n; |
||||
public final BigInteger ecc_gx; |
||||
public final BigInteger ecc_gy; |
||||
public final ECCurve ecc_curve; |
||||
public final ECPoint ecc_point_g; |
||||
public final ECDomainParameters ecc_bc_spec; |
||||
public final ECKeyPairGenerator ecc_key_pair_generator; |
||||
public final ECFieldElement ecc_gx_fieldelement; |
||||
public final ECFieldElement ecc_gy_fieldelement; |
||||
|
||||
public SM2() |
||||
{ |
||||
this.ecc_p = new BigInteger(ecc_param[0], 16); |
||||
this.ecc_a = new BigInteger(ecc_param[1], 16); |
||||
this.ecc_b = new BigInteger(ecc_param[2], 16); |
||||
this.ecc_n = new BigInteger(ecc_param[3], 16); |
||||
this.ecc_gx = new BigInteger(ecc_param[4], 16); |
||||
this.ecc_gy = new BigInteger(ecc_param[5], 16); |
||||
|
||||
this.ecc_gx_fieldelement = new Fp(this.ecc_p, this.ecc_gx); |
||||
this.ecc_gy_fieldelement = new Fp(this.ecc_p, this.ecc_gy); |
||||
|
||||
this.ecc_curve = new ECCurve.Fp(this.ecc_p, this.ecc_a, this.ecc_b); |
||||
this.ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement, this.ecc_gy_fieldelement,false); |
||||
|
||||
this.ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n); |
||||
|
||||
ECKeyGenerationParameters ecc_ecgenparam; |
||||
ecc_ecgenparam = new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom()); |
||||
|
||||
this.ecc_key_pair_generator = new ECKeyPairGenerator(); |
||||
this.ecc_key_pair_generator.init(ecc_ecgenparam); |
||||
} |
||||
} |
@ -0,0 +1,208 @@ |
||||
package cn.org.landcloud.security.sm2; |
||||
|
||||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair; |
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters; |
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters; |
||||
import org.bouncycastle.math.ec.ECPoint; |
||||
|
||||
import java.io.IOException; |
||||
import java.math.BigInteger; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
|
||||
public class SM2EncDecUtils { |
||||
//生成随机秘钥对
|
||||
public static SM2KeyVO generateKeyPair(){ |
||||
SM2 sm2 = SM2.Instance(); |
||||
AsymmetricCipherKeyPair key = null; |
||||
while (true){ |
||||
key=sm2.ecc_key_pair_generator.generateKeyPair(); |
||||
if(((ECPrivateKeyParameters) key.getPrivate()).getD().toByteArray().length==32){ |
||||
break; |
||||
} |
||||
} |
||||
ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate(); |
||||
ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic(); |
||||
BigInteger privateKey = ecpriv.getD(); |
||||
ECPoint publicKey = ecpub.getQ(); |
||||
SM2KeyVO sm2KeyVO = new SM2KeyVO(); |
||||
sm2KeyVO.setPublicKey(publicKey); |
||||
sm2KeyVO.setPrivateKey(privateKey); |
||||
//System.out.println("公钥: " + Util.byteToHex(publicKey.getEncoded()));
|
||||
//System.out.println("私钥: " + Util.byteToHex(privateKey.toByteArray()));
|
||||
return sm2KeyVO; |
||||
} |
||||
|
||||
//数据加密
|
||||
public static String encrypt(byte[] publicKey, byte[] data) throws IOException |
||||
{ |
||||
if (publicKey == null || publicKey.length == 0) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
if (data == null || data.length == 0) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
byte[] source = new byte[data.length]; |
||||
System.arraycopy(data, 0, source, 0, data.length); |
||||
|
||||
Cipher cipher = new Cipher(); |
||||
SM2 sm2 = SM2.Instance(); |
||||
ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey); |
||||
|
||||
ECPoint c1 = cipher.Init_enc(sm2, userKey); |
||||
cipher.Encrypt(source); |
||||
byte[] c3 = new byte[32]; |
||||
cipher.Dofinal(c3); |
||||
|
||||
// System.out.println("C1 " + Util.byteToHex(c1.getEncoded()));
|
||||
// System.out.println("C2 " + Util.byteToHex(source));
|
||||
// System.out.println("C3 " + Util.byteToHex(c3));
|
||||
//C1 C2 C3拼装成加密字串
|
||||
// C1 | C2 | C3
|
||||
//return Util.byteToHex(c1.getEncoded()) + Util.byteToHex(source) + Util.byteToHex(c3);
|
||||
// C1 | C3 | C2
|
||||
return Util.byteToHex(c1.getEncoded()) + Util.byteToHex(c3) + Util.byteToHex(source); |
||||
} |
||||
|
||||
//数据解密
|
||||
public static byte[] decrypt(byte[] privateKey, byte[] encryptedData) throws IOException |
||||
{ |
||||
if (privateKey == null || privateKey.length == 0) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
if (encryptedData == null || encryptedData.length == 0) |
||||
{ |
||||
return null; |
||||
} |
||||
//加密字节数组转换为十六进制的字符串 长度变为encryptedData.length * 2
|
||||
String data = Util.byteToHex(encryptedData); |
||||
/***分解加密字串 C1 | C2 | C3 |
||||
* (C1 = C1标志位2位 + C1实体部分128位 = 130) |
||||
* (C3 = C3实体部分64位 = 64) |
||||
* (C2 = encryptedData.length * 2 - C1长度 - C2长度) |
||||
|
||||
byte[] c1Bytes = Util.hexToByte(data.substring(0,130)); |
||||
int c2Len = encryptedData.length - 97; |
||||
byte[] c2 = Util.hexToByte(data.substring(130,130 + 2 * c2Len)); |
||||
byte[] c3 = Util.hexToByte(data.substring(130 + 2 * c2Len,194 + 2 * c2Len)); |
||||
*/ |
||||
/***分解加密字串 C1 | C3 | C2 |
||||
* (C1 = C1标志位2位 + C1实体部分128位 = 130) |
||||
* (C3 = C3实体部分64位 = 64) |
||||
* (C2 = encryptedData.length * 2 - C1长度 - C2长度) |
||||
*/ |
||||
byte[] c1Bytes = Util.hexToByte(data.substring(0,130)); |
||||
int c2Len = encryptedData.length - 97; |
||||
byte[] c3 = Util.hexToByte(data.substring(130,130 + 64)); |
||||
byte[] c2 = Util.hexToByte(data.substring(194,194 + 2 * c2Len)); |
||||
|
||||
SM2 sm2 = SM2.Instance(); |
||||
BigInteger userD = new BigInteger(1, privateKey); |
||||
|
||||
//通过C1实体字节来生成ECPoint
|
||||
ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes); |
||||
Cipher cipher = new Cipher(); |
||||
cipher.Init_dec(userD, c1); |
||||
cipher.Decrypt(c2); |
||||
cipher.Dofinal(c3); |
||||
|
||||
//返回解密结果
|
||||
return c2; |
||||
} |
||||
|
||||
/* public static BigInteger[] Sm2Sign(byte[] md, AsymmetricCipherKeyPair keypair) |
||||
{ |
||||
SM3Digest sm3 = new SM3Digest(); |
||||
|
||||
ECPublicKeyParameters ecpub = (ECPublicKeyParameters)keypair.getPublic(); |
||||
|
||||
byte[] z = SM2CryptoServiceProvider.Sm2GetZ(Encoding.Default.GetBytes(SM2CryptoServiceProvider.userId), ecpub.getQ()); |
||||
sm3.update(z, 0, z.length); |
||||
|
||||
byte[] p = md; |
||||
sm3.update(p, 0, p.length); |
||||
|
||||
byte[] hashData = new byte[32]; |
||||
sm3.doFinal(hashData, 0); |
||||
|
||||
// e
|
||||
BigInteger e = new BigInteger(1, hashData); |
||||
// k
|
||||
BigInteger k = null; |
||||
ECPoint kp = null; |
||||
BigInteger r = null; |
||||
BigInteger s = null; |
||||
BigInteger userD = null; |
||||
|
||||
do |
||||
{ |
||||
do |
||||
{ |
||||
|
||||
ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)keypair.getPrivate(); |
||||
k = ecpriv.getD(); |
||||
kp = ecpub.getQ(); |
||||
|
||||
userD = ecpriv.getD(); |
||||
|
||||
// r
|
||||
r = e.add(kp.getX().toBigInteger()); |
||||
r = r.mod(ecc_n); |
||||
} |
||||
while (r.equals(BigInteger.ZERO) || r.add(k).equals(ecc_n)); |
||||
|
||||
// (1 + dA)~-1
|
||||
BigInteger da_1 = userD.add(BigInteger.ONE); |
||||
da_1 = da_1.modInverse(ecc_n); |
||||
// s
|
||||
s = r.multiply(userD); |
||||
s = k.subtract(s).mod(ecc_n); |
||||
s = da_1.multiply(s).mod(ecc_n); |
||||
} |
||||
while (s.equals(BigInteger.ZERO)); |
||||
|
||||
byte[] btRS = new byte[64]; |
||||
byte[] btR = r.toByteArray(); |
||||
byte[] btS = s.toByteArray(); |
||||
Array.Copy(btR, btR.length - 32, btRS, 0, 32); |
||||
Array.Copy(btS, btS.length - 32, btRS, 32, 32); |
||||
|
||||
return new BigInteger[] { r, s }; |
||||
}*/ |
||||
|
||||
public static void main(String[] args) throws Exception |
||||
{ |
||||
String plainText = "ILoveYou11"; |
||||
//SM3测试
|
||||
//生成密钥对
|
||||
//generateKeyPair();
|
||||
byte[] sourceData = plainText.getBytes(); |
||||
|
||||
//下面的秘钥可以使用generateKeyPair()生成的秘钥内容
|
||||
// 国密规范正式私钥
|
||||
//String prik = "3690655E33D5EA3D9A4AE1A1ADD766FDEA045CDEAA43A9206FB8C430CEFE0D94";
|
||||
// 国密规范正式公钥
|
||||
//String pubk = "04F6E0C3345AE42B51E06BF50B98834988D54EBC7460FE135A48171BC0629EAE205EEDE253A530608178A98F1E19BB737302813BA39ED3FA3C51639D7A20C7391A";
|
||||
|
||||
String prik = "4cf170068e9c47ebdb521fb9fc62c4a55a5773fb9da33b0acf8129e28d09d205"; |
||||
String pubk = "04aabda53043e8dcb86d42f690b61a4db869821dadf9f851ec3c5c43d0c8f95a6677fdba984afc3bb010a8436b1d17cefc2011a34e01e9e801124d29ffa928d803"; |
||||
String publicKey ="04BB34D657EE7E8490E66EF577E6B3CEA28B739511E787FB4F71B7F38F241D87F18A5A93DF74E90FF94F4EB907F271A36B295B851F971DA5418F4915E2C1A23D6E"; |
||||
String privatekey = "0B1CE43098BC21B8E82B5C065EDB534CB86532B1900A49D49F3C53762D2997FA"; |
||||
prik=privatekey; |
||||
pubk=publicKey; |
||||
System.out.println("加密: "); |
||||
String cipherText = SM2EncDecUtils.encrypt(Util.hexToByte(pubk), sourceData); |
||||
//cipherText = "0452ba81cf5119c9f29c81c2be9c4a49ad8c0a33ed899b60548d21a62971a8e994cafc0e9fbc710a0a220b055804bb890833b50ac04ec4e130a5db75338c0c1d49a52a6d373076a5db370564a5cebb5300f79877003c52adf49dac16370e51e14e0754110547bb3b";
|
||||
System.out.println(cipherText); |
||||
System.out.println("解密: "); |
||||
plainText = new String(SM2EncDecUtils.decrypt(Util.hexToByte(prik), Util.hexToByte(cipherText))); |
||||
System.out.println(plainText); |
||||
|
||||
} |
||||
} |
@ -0,0 +1,179 @@ |
||||
package cn.org.landcloud.security.sm2; |
||||
|
||||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair; |
||||
import org.bouncycastle.crypto.digests.SM3Digest; |
||||
import org.bouncycastle.crypto.generators.ECKeyPairGenerator; |
||||
import org.bouncycastle.crypto.params.ECDomainParameters; |
||||
import org.bouncycastle.crypto.params.ECKeyGenerationParameters; |
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters; |
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters; |
||||
import org.bouncycastle.math.ec.ECCurve; |
||||
import org.bouncycastle.math.ec.ECFieldElement; |
||||
import org.bouncycastle.math.ec.ECFieldElement.Fp; |
||||
import org.bouncycastle.math.ec.ECPoint; |
||||
|
||||
import java.math.BigInteger; |
||||
import java.security.SecureRandom; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
|
||||
|
||||
public class SM2Factory { |
||||
/*-----------------------国密算法相关参数begin----------- |
||||
* ------------------*/ |
||||
//A 第一系数
|
||||
private static final BigInteger a = new BigInteger("fffffffeffffffffffffffffffffffffffffffff00000000fffffffffffffffc",16); |
||||
//B 第二系数
|
||||
private static final BigInteger b = new BigInteger("28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92ddbcbd414d940e93",16); |
||||
//曲线X系数
|
||||
private static final BigInteger gx = new BigInteger("32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7",16); |
||||
//曲线Y系数
|
||||
private static final BigInteger gy = new BigInteger("bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0",16); |
||||
//生产者顺序系数
|
||||
private static final BigInteger n = new BigInteger("fffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123",16); |
||||
//素数
|
||||
private static final BigInteger p = new BigInteger("fffffffeffffffffffffffffffffffffffffffff00000000ffffffffffffffff",16); |
||||
//因子系数 1
|
||||
private static final int h = 1; |
||||
/*-----------------------国密算法相关参数end-----------------------------*/ |
||||
//一些必要类
|
||||
public final ECFieldElement ecc_gx_fieldelement; |
||||
public final ECFieldElement ecc_gy_fieldelement; |
||||
public final ECCurve ecc_curve; |
||||
public final ECPoint ecc_point_g; |
||||
public final ECDomainParameters ecc_bc_spec; |
||||
public final ECKeyPairGenerator ecc_key_pair_generator; |
||||
/** |
||||
* 初始化方法 |
||||
* @return |
||||
*/ |
||||
public static SM2Factory getInstance(){ |
||||
return new SM2Factory(); |
||||
} |
||||
public SM2Factory() { |
||||
|
||||
this.ecc_gx_fieldelement = new Fp(this.p,this.gx); |
||||
this.ecc_gy_fieldelement = new Fp(this.p, this.gy); |
||||
|
||||
this.ecc_curve = new ECCurve.Fp(this.p, this.a, this.b); |
||||
|
||||
this.ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement,this.ecc_gy_fieldelement,false); |
||||
this.ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.n); |
||||
|
||||
ECKeyGenerationParameters ecc_ecgenparam; |
||||
ecc_ecgenparam = new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom()); |
||||
|
||||
this.ecc_key_pair_generator = new ECKeyPairGenerator(); |
||||
this.ecc_key_pair_generator.init(ecc_ecgenparam); |
||||
} |
||||
/** |
||||
* 根据私钥、曲线参数计算Z |
||||
* @param userId |
||||
* @param userKey |
||||
* @return |
||||
*/ |
||||
public byte[] sm2GetZ(byte[] userId, ECPoint userKey){ |
||||
SM3Digest sm3 = new SM3Digest(); |
||||
|
||||
int len = userId.length * 8; |
||||
sm3.update((byte) (len >> 8 & 0xFF)); |
||||
sm3.update((byte) (len & 0xFF)); |
||||
sm3.update(userId, 0, userId.length); |
||||
|
||||
byte[] p = Util.byteConvert32Bytes(this.a); |
||||
sm3.update(p, 0, p.length); |
||||
|
||||
p = Util.byteConvert32Bytes(this.b); |
||||
sm3.update(p, 0, p.length); |
||||
|
||||
p = Util.byteConvert32Bytes(this.gx); |
||||
sm3.update(p, 0, p.length); |
||||
|
||||
p = Util.byteConvert32Bytes(this.gy); |
||||
sm3.update(p, 0, p.length); |
||||
|
||||
p = Util.byteConvert32Bytes(userKey.normalize().getXCoord().toBigInteger()); |
||||
sm3.update(p, 0, p.length); |
||||
|
||||
p = Util.byteConvert32Bytes(userKey.normalize().getYCoord().toBigInteger()); |
||||
sm3.update(p, 0, p.length); |
||||
|
||||
byte[] md = new byte[sm3.getDigestSize()]; |
||||
sm3.doFinal(md, 0); |
||||
return md; |
||||
} |
||||
/** |
||||
* 签名相关值计算 |
||||
* @param md |
||||
* @param userD |
||||
* @param userKey |
||||
* @param sm2Result |
||||
*/ |
||||
public void sm2Sign(byte[] md, BigInteger userD, ECPoint userKey, SM2Result sm2Result) { |
||||
BigInteger e = new BigInteger(1, md); |
||||
BigInteger k = null; |
||||
ECPoint kp = null; |
||||
BigInteger r = null; |
||||
BigInteger s = null; |
||||
do { |
||||
do { |
||||
// 正式环境
|
||||
AsymmetricCipherKeyPair keypair = ecc_key_pair_generator.generateKeyPair(); |
||||
ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) keypair.getPrivate(); |
||||
ECPublicKeyParameters ecpub = (ECPublicKeyParameters) keypair.getPublic(); |
||||
k = ecpriv.getD(); |
||||
kp = ecpub.getQ(); |
||||
//System.out.println("BigInteger:" + k + "\nECPoint:" + kp);
|
||||
|
||||
//System.out.println("计算曲线点X1: "+ kp.getXCoord().toBigInteger().toString(16));
|
||||
//System.out.println("计算曲线点Y1: "+ kp.getYCoord().toBigInteger().toString(16));
|
||||
//System.out.println("");
|
||||
// r
|
||||
r = e.add(kp.getXCoord().toBigInteger()); |
||||
r = r.mod(this.n); |
||||
} while (r.equals(BigInteger.ZERO) || r.add(k).equals(this.n)||r.toString(16).length()!=64); |
||||
|
||||
// (1 + dA)~-1
|
||||
BigInteger da_1 = userD.add(BigInteger.ONE); |
||||
da_1 = da_1.modInverse(this.n); |
||||
// s
|
||||
s = r.multiply(userD); |
||||
s = k.subtract(s).mod(this.n); |
||||
s = da_1.multiply(s).mod(this.n); |
||||
} while (s.equals(BigInteger.ZERO)||(s.toString(16).length()!=64)); |
||||
|
||||
sm2Result.r = r; |
||||
sm2Result.s = s; |
||||
} |
||||
/** |
||||
* 验签 |
||||
* @param md sm3摘要 |
||||
* @param userKey 根据公钥decode一个ecpoint对象 |
||||
* @param r 没有特殊含义 |
||||
* @param s 没有特殊含义 |
||||
* @param sm2Result 接收参数的对象 |
||||
*/ |
||||
public void sm2Verify(byte md[], ECPoint userKey, BigInteger r, |
||||
BigInteger s, SM2Result sm2Result) { |
||||
sm2Result.R = null; |
||||
BigInteger e = new BigInteger(1, md); |
||||
BigInteger t = r.add(s).mod(this.n); |
||||
if (t.equals(BigInteger.ZERO)) { |
||||
return; |
||||
} else { |
||||
ECPoint x1y1 = ecc_point_g.multiply(sm2Result.s); |
||||
//System.out.println("计算曲线点X0: "+ x1y1.normalize().getXCoord().toBigInteger().toString(16));
|
||||
//System.out.println("计算曲线点Y0: "+ x1y1.normalize().getYCoord().toBigInteger().toString(16));
|
||||
//System.out.println("");
|
||||
|
||||
x1y1 = x1y1.add(userKey.multiply(t)); |
||||
//System.out.println("计算曲线点X1: "+ x1y1.normalize().getXCoord().toBigInteger().toString(16));
|
||||
//System.out.println("计算曲线点Y1: "+ x1y1.normalize().getYCoord().toBigInteger().toString(16));
|
||||
//System.out.println("");
|
||||
sm2Result.R = e.add(x1y1.normalize().getXCoord().toBigInteger()).mod(this.n); |
||||
//System.out.println("R: " + sm2Result.R.toString(16));
|
||||
return; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,42 @@ |
||||
package cn.org.landcloud.security.sm2; |
||||
|
||||
import org.bouncycastle.math.ec.ECPoint; |
||||
|
||||
import java.math.BigInteger; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
|
||||
public class SM2KeyVO { |
||||
BigInteger privateKey ; |
||||
ECPoint publicKey ; |
||||
|
||||
public BigInteger getPrivateKey() { |
||||
return privateKey; |
||||
} |
||||
|
||||
public void setPrivateKey(BigInteger privateKey) { |
||||
this.privateKey = privateKey; |
||||
} |
||||
|
||||
public ECPoint getPublicKey() { |
||||
return publicKey; |
||||
} |
||||
|
||||
public void setPublicKey(ECPoint publicKey) { |
||||
this.publicKey = publicKey; |
||||
} |
||||
|
||||
|
||||
//HardPubKey:3059301306072A8648CE3D020106082A811CCF5501822D03420004+X+Y
|
||||
//SoftPubKey:04+X+Y
|
||||
public String getPubHexInSoft(){ |
||||
return Util.byteToHex(publicKey.getEncoded()); |
||||
//System.out.println("公钥: " + );
|
||||
} |
||||
/*public String getPubHexInHard(){ |
||||
return SecurityTestAll.SM2PubHardKeyHead +Util.byteToHex(publicKey.getEncoded()); |
||||
}*/ |
||||
public String getPriHexInSoft(){ |
||||
return Util.byteToHex(privateKey.toByteArray()); |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
package cn.org.landcloud.security.sm2; |
||||
|
||||
import org.bouncycastle.math.ec.ECPoint; |
||||
|
||||
import java.math.BigInteger; |
||||
|
||||
/** |
||||
* SM2 |
||||
*/ |
||||
public class SM2Result { |
||||
public SM2Result() { |
||||
} |
||||
// 签名r
|
||||
public BigInteger r; |
||||
public BigInteger s; |
||||
//验签R
|
||||
public BigInteger R; |
||||
|
||||
// 密钥交换
|
||||
public byte[] sa; |
||||
public byte[] sb; |
||||
public byte[] s1; |
||||
public byte[] s2; |
||||
|
||||
public ECPoint keyra; |
||||
public ECPoint keyrb; |
||||
|
||||
} |
@ -0,0 +1,116 @@ |
||||
package cn.org.landcloud.security.sm2; |
||||
|
||||
/** |
||||
* SM2签名所计算的值 可以根据实际情况增加删除字段属性 |
||||
*/ |
||||
public class SM2SignVO { |
||||
//16进制的私钥
|
||||
public String sm2_userd; |
||||
//椭圆曲线点X
|
||||
public String x_coord; |
||||
//椭圆曲线点Y
|
||||
public String y_coord; |
||||
//SM3摘要Z
|
||||
public String sm3_z; |
||||
//明文数据16进制
|
||||
public String sign_express; |
||||
//SM3摘要值
|
||||
public String sm3_digest; |
||||
//R
|
||||
public String sign_r; |
||||
//S
|
||||
public String sign_s; |
||||
//R
|
||||
public String verify_r; |
||||
//S
|
||||
public String verify_s; |
||||
//签名值
|
||||
public String sm2_sign; |
||||
//sign 签名 verfiy验签
|
||||
public String sm2_type; |
||||
//是否验签成功 true false
|
||||
public boolean isVerify; |
||||
public String getX_coord() { |
||||
return x_coord; |
||||
} |
||||
public void setX_coord(String x_coord) { |
||||
this.x_coord = x_coord; |
||||
} |
||||
public String getY_coord() { |
||||
return y_coord; |
||||
} |
||||
public void setY_coord(String y_coord) { |
||||
this.y_coord = y_coord; |
||||
} |
||||
public String getSm3_z() { |
||||
return sm3_z; |
||||
} |
||||
public void setSm3_z(String sm3_z) { |
||||
this.sm3_z = sm3_z; |
||||
} |
||||
public String getSm3_digest() { |
||||
return sm3_digest; |
||||
} |
||||
public void setSm3_digest(String sm3_digest) { |
||||
this.sm3_digest = sm3_digest; |
||||
} |
||||
public String getSm2_signForSoft() { |
||||
return sm2_sign; |
||||
} |
||||
public String getSm2_signForHard() { |
||||
//System.out.println("R:"+getSign_r());
|
||||
//System.out.println("s:"+getSign_s());
|
||||
return getSign_r()+getSign_s(); |
||||
} |
||||
public void setSm2_sign(String sm2_sign) { |
||||
this.sm2_sign = sm2_sign; |
||||
} |
||||
public String getSign_express() { |
||||
return sign_express; |
||||
} |
||||
public void setSign_express(String sign_express) { |
||||
this.sign_express = sign_express; |
||||
} |
||||
public String getSm2_userd() { |
||||
return sm2_userd; |
||||
} |
||||
public void setSm2_userd(String sm2_userd) { |
||||
this.sm2_userd = sm2_userd; |
||||
} |
||||
public String getSm2_type() { |
||||
return sm2_type; |
||||
} |
||||
public void setSm2_type(String sm2_type) { |
||||
this.sm2_type = sm2_type; |
||||
} |
||||
public boolean isVerify() { |
||||
return isVerify; |
||||
} |
||||
public void setVerify(boolean isVerify) { |
||||
this.isVerify = isVerify; |
||||
} |
||||
public String getSign_r() { |
||||
return sign_r; |
||||
} |
||||
public void setSign_r(String sign_r) { |
||||
this.sign_r = sign_r; |
||||
} |
||||
public String getSign_s() { |
||||
return sign_s; |
||||
} |
||||
public void setSign_s(String sign_s) { |
||||
this.sign_s = sign_s; |
||||
} |
||||
public String getVerify_r() { |
||||
return verify_r; |
||||
} |
||||
public void setVerify_r(String verify_r) { |
||||
this.verify_r = verify_r; |
||||
} |
||||
public String getVerify_s() { |
||||
return verify_s; |
||||
} |
||||
public void setVerify_s(String verify_s) { |
||||
this.verify_s = verify_s; |
||||
} |
||||
} |
@ -0,0 +1,166 @@ |
||||
package cn.org.landcloud.security.sm2; |
||||
|
||||
import org.bouncycastle.asn1.*; |
||||
import org.bouncycastle.crypto.digests.SM3Digest; |
||||
import org.bouncycastle.math.ec.ECPoint; |
||||
|
||||
import java.io.ByteArrayInputStream; |
||||
import java.math.BigInteger; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.Enumeration; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
import cn.org.landcloud.security.sm3.SM3Utils; |
||||
|
||||
/** |
||||
* 国密算法的签名、验签 |
||||
*/ |
||||
public class SM2SignVerUtils { |
||||
/** |
||||
* 默认USERID |
||||
*/ |
||||
public static String USER_ID = "1234567812345678"; |
||||
/** |
||||
* 私钥签名 |
||||
* 使用SM3进行对明文数据计算一个摘要值 |
||||
* @param privatekey 私钥 |
||||
* @param sourceData 明文数据 |
||||
* @return 签名后的值 |
||||
* @throws Exception |
||||
*/ |
||||
public static SM2SignVO Sign2SM2(byte[] privatekey,byte[] sourceData) throws Exception{ |
||||
SM2SignVO sm2SignVO = new SM2SignVO(); |
||||
sm2SignVO.setSm2_type("sign"); |
||||
SM2Factory factory = SM2Factory.getInstance(); |
||||
BigInteger userD = new BigInteger(1,privatekey); |
||||
//System.out.println("userD:"+userD.toString(16));
|
||||
sm2SignVO.setSm2_userd(userD.toString(16)); |
||||
|
||||
ECPoint userKey = factory.ecc_point_g.multiply(userD); |
||||
//System.out.println("椭圆曲线点X: "+ userKey.getXCoord().toBigInteger().toString(16));
|
||||
//System.out.println("椭圆曲线点Y: "+ userKey.getYCoord().toBigInteger().toString(16));
|
||||
|
||||
SM3Digest sm3Digest = new SM3Digest(); |
||||
byte [] z = factory.sm2GetZ(USER_ID.getBytes(), userKey); |
||||
//System.out.println("SM3摘要Z: " + Util.getHexString(z));
|
||||
//System.out.println("被加密数据的16进制: " + Util.getHexString(sourceData));
|
||||
sm2SignVO.setSm3_z(Util.getHexString(z)); |
||||
sm2SignVO.setSign_express(Util.getHexString(sourceData)); |
||||
|
||||
sm3Digest.update(z, 0, z.length); |
||||
sm3Digest.update(sourceData,0,sourceData.length); |
||||
byte [] md = new byte[32]; |
||||
sm3Digest.doFinal(md, 0); |
||||
//System.out.println("SM3摘要值: " + Util.getHexString(md));
|
||||
sm2SignVO.setSm3_digest(Util.getHexString(md)); |
||||
|
||||
SM2Result sm2Result = new SM2Result(); |
||||
factory.sm2Sign(md, userD, userKey, sm2Result); |
||||
//System.out.println("r: " + sm2Result.r.toString(16));
|
||||
//System.out.println("s: " + sm2Result.s.toString(16));
|
||||
// sm2SignVO.setSign_r(sm2Result.r.toString(16));
|
||||
// sm2SignVO.setSign_s(sm2Result.s.toString(16));
|
||||
|
||||
sm2SignVO.setSign_r(Util.byteToHex(sm2Result.r.toByteArray())); |
||||
sm2SignVO.setSign_s(Util.byteToHex(sm2Result.s.toByteArray())); |
||||
|
||||
ASN1Integer d_r = new ASN1Integer(sm2Result.r); |
||||
ASN1Integer d_s = new ASN1Integer(sm2Result.s); |
||||
ASN1EncodableVector v2 = new ASN1EncodableVector(); |
||||
v2.add(d_r); |
||||
v2.add(d_s); |
||||
DERSequence sign = new DERSequence(v2); |
||||
String result = Util.byteToHex(sign.getEncoded()); |
||||
sm2SignVO.setSm2_sign(result); |
||||
return sm2SignVO; |
||||
} |
||||
/** |
||||
* 验证签名 |
||||
* @param publicKey 公钥信息 |
||||
* @param sourceData 密文信息 |
||||
* @param signData 签名信息 |
||||
* @return 验签的对象 包含了相关参数和验签结果 |
||||
*/ |
||||
@SuppressWarnings("unchecked") |
||||
public static SM2SignVO VerifySignSM2(byte[] publicKey,byte[] sourceData,byte[] signData){ |
||||
try { |
||||
byte[] formatedPubKey; |
||||
SM2SignVO verifyVo = new SM2SignVO(); |
||||
verifyVo.setSm2_type("verify"); |
||||
if (publicKey.length == 64) { |
||||
// 添加一字节标识,用于ECPoint解析
|
||||
formatedPubKey = new byte[65]; |
||||
formatedPubKey[0] = 0x04; |
||||
System.arraycopy(publicKey, 0, formatedPubKey, 1, publicKey.length); |
||||
} else{ |
||||
formatedPubKey = publicKey; |
||||
} |
||||
SM2Factory factory = SM2Factory.getInstance(); |
||||
ECPoint userKey = factory.ecc_curve.decodePoint(formatedPubKey); |
||||
|
||||
SM3Digest sm3Digest = new SM3Digest(); |
||||
byte [] z = factory.sm2GetZ(USER_ID.getBytes(), userKey); |
||||
//System.out.println("SM3摘要Z: " + Util.getHexString(z));
|
||||
verifyVo.setSm3_z(Util.getHexString(z)); |
||||
sm3Digest.update(z,0,z.length); |
||||
sm3Digest.update(sourceData,0,sourceData.length); |
||||
byte [] md = new byte[32]; |
||||
sm3Digest.doFinal(md, 0); |
||||
//System.out.println("SM3摘要值: " + Util.getHexString(md));
|
||||
verifyVo.setSm3_digest(Util.getHexString(md)); |
||||
ByteArrayInputStream bis = new ByteArrayInputStream(signData); |
||||
ASN1InputStream dis = new ASN1InputStream(bis); |
||||
SM2Result sm2Result = null; |
||||
ASN1Primitive derObj = dis.readObject(); |
||||
Enumeration<ASN1Integer> e = ((ASN1Sequence)derObj).getObjects(); |
||||
BigInteger r = ((ASN1Integer) e.nextElement()).getValue(); |
||||
BigInteger s = ((ASN1Integer) e.nextElement()).getValue(); |
||||
sm2Result = new SM2Result(); |
||||
sm2Result.r = r; |
||||
sm2Result.s = s; |
||||
//System.out.println("vr: " + sm2Result.r.toString(16));
|
||||
//System.out.println("vs: " + sm2Result.s.toString(16));
|
||||
// verifyVo.setVerify_r(sm2Result.r.toString(16));
|
||||
// verifyVo.setVerify_s(sm2Result.s.toString(16));
|
||||
|
||||
verifyVo.setVerify_r(Util.byteToHex(sm2Result.r.toByteArray())); |
||||
verifyVo.setVerify_s(Util.byteToHex(sm2Result.s.toByteArray())); |
||||
|
||||
factory.sm2Verify(md, userKey, sm2Result.r, sm2Result.s, sm2Result); |
||||
boolean verifyFlag = sm2Result.r.equals(sm2Result.R); |
||||
verifyVo.setVerify(verifyFlag); |
||||
return verifyVo; |
||||
} catch (IllegalArgumentException e) { |
||||
return null; |
||||
}catch (Exception e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
public static void main(String[] args) throws Exception { |
||||
|
||||
// String text = "913301106798859401,杭州今奥信息科技股份有限公司,1001,12100000400010398P,中国国土勘测规划院,1697269051,047828D5466AB6AF21FD8528A901622AE100A3ED80E2AFEFAA093BEDF3662C5327305DAA0A853770BA0605F6266B05535ECCC7747BAA122F185C47D9F65E74E60C";
|
||||
String text = "0D9E4559EAA489079CA46A11BAD09528BDE0E2390226FD825AE1AC10DEA8FFEA,2022-10-18 15:42:56,119.98547,30.277615,41.0,239.0,2.0,test,1001"; |
||||
// byte [] sourceData = SM3Utils.sm3(text.toString()).getBytes(StandardCharsets.UTF_8);
|
||||
byte [] sourceData = text.getBytes(StandardCharsets.UTF_8); |
||||
//String publicKey ="FA05C51AD1162133DFDF862ECA5E4A481B52FB37FF83E53D45FD18BBD6F32668A92C4692EEB305684E3B9D4ACE767F91D5D108234A9F07936020A92210BA9447";
|
||||
//String privatekey = "5EB4DF17021CC719B678D970C620690A11B29C8357D71FA4FF9BF7FB6D89767A";
|
||||
// String publicKey ="04BB34D657EE7E8490E66EF577E6B3CEA28B739511E787FB4F71B7F38F241D87F18A5A93DF74E90FF94F4EB907F271A36B295B851F971DA5418F4915E2C1A23D6E";
|
||||
// String privatekey = "0B1CE43098BC21B8E82B5C065EDB534CB86532B1900A49D49F3C53762D2997FA";
|
||||
|
||||
// String publicKey = "048D9B68E8DECD33A19A73F87169BB4A65BFE557AA1F58462BAF5D63EFBC5EE5385D1184C3B2A5A0D6EE2ED401182D0E6AF362DCAA8931231399D941AD318D21AD";
|
||||
// String privatekey = "2DD789162386F0E0508D0B4AAE26BE9D7D4075CCBE7536200174FF8D200124B1";
|
||||
|
||||
String publicKey = "047828D5466AB6AF21FD8528A901622AE100A3ED80E2AFEFAA093BEDF3662C5327305DAA0A853770BA0605F6266B05535ECCC7747BAA122F185C47D9F65E74E60C"; |
||||
String privatekey = "00D7D395E6093C63A50A0370D5F6CD89964AB148A846EA96C9969AF08EC1E97513"; |
||||
|
||||
// String publicKey ="047828D5466AB6AF21FD8528A901622AE100A3ED80E2AFEFAA093BEDF3662C5327305DAA0A853770BA0605F6266B05535ECCC7747BAA122F185C47D9F65E74E60C";
|
||||
// String sign = "3046022100A1C51CF002DB42A35AFE36E43E63BDC920397EB101D6A62EC5E016FC4EFFE273022100C3594CBB9D4A5401833F0057F4EC77B41899699C98F5BEF0F079B3BA9D3EB324";
|
||||
SM2SignVO sign = SM2SignVerUtils.Sign2SM2(Util.hexStringToBytes(privatekey), sourceData); |
||||
// SM2SignVO verify = SM2SignVerUtils.VerifySignSM2(Util.hexStringToBytes(publicKey), SM3Utils.sm3(text.toString()).getBytes(StandardCharsets.UTF_8), Util.hexStringToBytes(sign));
|
||||
SM2SignVO verify = SM2SignVerUtils.VerifySignSM2(Util.hexStringToBytes(publicKey), sourceData, Util.hexStringToBytes(sign.getSm2_signForSoft())); |
||||
System.out.println("签名得到的r值:"+sign.getSign_r()+"\n签名值 "+sign.getSm2_signForSoft()); |
||||
System.out.println("验签得到的R值:"+verify.getVerify_r()); |
||||
System.err.println("\n验签结果" +verify.isVerify()); |
||||
} |
||||
} |
@ -0,0 +1,328 @@ |
||||
package cn.org.landcloud.security.sm3; |
||||
|
||||
import org.bouncycastle.crypto.digests.SM3Digest; |
||||
import org.bouncycastle.util.encoders.Hex; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
|
||||
/** |
||||
* Created by $(USER) on $(DATE) |
||||
*/ |
||||
public class SM3 { |
||||
public static final byte[] iv = { 0x73, (byte) 0x80, 0x16, 0x6f, 0x49, |
||||
0x14, (byte) 0xb2, (byte) 0xb9, 0x17, 0x24, 0x42, (byte) 0xd7, |
||||
(byte) 0xda, (byte) 0x8a, 0x06, 0x00, (byte) 0xa9, 0x6f, 0x30, |
||||
(byte) 0xbc, (byte) 0x16, 0x31, 0x38, (byte) 0xaa, (byte) 0xe3, |
||||
(byte) 0x8d, (byte) 0xee, 0x4d, (byte) 0xb0, (byte) 0xfb, 0x0e, |
||||
0x4e }; |
||||
|
||||
public static int[] Tj = new int[64]; |
||||
|
||||
static |
||||
{ |
||||
for (int i = 0; i < 16; i++) |
||||
{ |
||||
Tj[i] = 0x79cc4519; |
||||
} |
||||
|
||||
for (int i = 16; i < 64; i++) |
||||
{ |
||||
Tj[i] = 0x7a879d8a; |
||||
} |
||||
} |
||||
|
||||
public static byte[] CF(byte[] V, byte[] B) |
||||
{ |
||||
int[] v, b; |
||||
v = convert(V); |
||||
b = convert(B); |
||||
return convert(CF(v, b)); |
||||
} |
||||
|
||||
private static int[] convert(byte[] arr) |
||||
{ |
||||
int[] out = new int[arr.length / 4]; |
||||
byte[] tmp = new byte[4]; |
||||
for (int i = 0; i < arr.length; i += 4) |
||||
{ |
||||
System.arraycopy(arr, i, tmp, 0, 4); |
||||
out[i / 4] = bigEndianByteToInt(tmp); |
||||
} |
||||
return out; |
||||
} |
||||
|
||||
private static byte[] convert(int[] arr) |
||||
{ |
||||
byte[] out = new byte[arr.length * 4]; |
||||
byte[] tmp = null; |
||||
for (int i = 0; i < arr.length; i++) |
||||
{ |
||||
tmp = bigEndianIntToByte(arr[i]); |
||||
System.arraycopy(tmp, 0, out, i * 4, 4); |
||||
} |
||||
return out; |
||||
} |
||||
|
||||
public static int[] CF(int[] V, int[] B) |
||||
{ |
||||
int a, b, c, d, e, f, g, h; |
||||
int ss1, ss2, tt1, tt2; |
||||
a = V[0]; |
||||
b = V[1]; |
||||
c = V[2]; |
||||
d = V[3]; |
||||
e = V[4]; |
||||
f = V[5]; |
||||
g = V[6]; |
||||
h = V[7]; |
||||
|
||||
int[][] arr = expand(B); |
||||
int[] w = arr[0]; |
||||
int[] w1 = arr[1]; |
||||
|
||||
for (int j = 0; j < 64; j++) |
||||
{ |
||||
ss1 = (bitCycleLeft(a, 12) + e + bitCycleLeft(Tj[j], j)); |
||||
ss1 = bitCycleLeft(ss1, 7); |
||||
ss2 = ss1 ^ bitCycleLeft(a, 12); |
||||
tt1 = FFj(a, b, c, j) + d + ss2 + w1[j]; |
||||
tt2 = GGj(e, f, g, j) + h + ss1 + w[j]; |
||||
d = c; |
||||
c = bitCycleLeft(b, 9); |
||||
b = a; |
||||
a = tt1; |
||||
h = g; |
||||
g = bitCycleLeft(f, 19); |
||||
f = e; |
||||
e = P0(tt2); |
||||
|
||||
/*System.out.print(j+" "); |
||||
System.out.print(Integer.toHexString(a)+" "); |
||||
System.out.print(Integer.toHexString(b)+" "); |
||||
System.out.print(Integer.toHexString(c)+" "); |
||||
System.out.print(Integer.toHexString(d)+" "); |
||||
System.out.print(Integer.toHexString(e)+" "); |
||||
System.out.print(Integer.toHexString(f)+" "); |
||||
System.out.print(Integer.toHexString(g)+" "); |
||||
System.out.print(Integer.toHexString(h)+" "); |
||||
System.out.println("");*/ |
||||
} |
||||
// System.out.println("");
|
||||
|
||||
int[] out = new int[8]; |
||||
out[0] = a ^ V[0]; |
||||
out[1] = b ^ V[1]; |
||||
out[2] = c ^ V[2]; |
||||
out[3] = d ^ V[3]; |
||||
out[4] = e ^ V[4]; |
||||
out[5] = f ^ V[5]; |
||||
out[6] = g ^ V[6]; |
||||
out[7] = h ^ V[7]; |
||||
|
||||
return out; |
||||
} |
||||
|
||||
private static int[][] expand(int[] B) |
||||
{ |
||||
int W[] = new int[68]; |
||||
int W1[] = new int[64]; |
||||
for (int i = 0; i < B.length; i++) |
||||
{ |
||||
W[i] = B[i]; |
||||
} |
||||
|
||||
for (int i = 16; i < 68; i++) |
||||
{ |
||||
W[i] = P1(W[i - 16] ^ W[i - 9] ^ bitCycleLeft(W[i - 3], 15)) |
||||
^ bitCycleLeft(W[i - 13], 7) ^ W[i - 6]; |
||||
} |
||||
|
||||
for (int i = 0; i < 64; i++) |
||||
{ |
||||
W1[i] = W[i] ^ W[i + 4]; |
||||
} |
||||
|
||||
int arr[][] = new int[][] { W, W1 }; |
||||
return arr; |
||||
} |
||||
|
||||
private static byte[] bigEndianIntToByte(int num) |
||||
{ |
||||
return back(Util.intToBytes(num)); |
||||
} |
||||
|
||||
private static int bigEndianByteToInt(byte[] bytes) |
||||
{ |
||||
return Util.byteToInt(back(bytes)); |
||||
} |
||||
|
||||
private static int FFj(int X, int Y, int Z, int j) |
||||
{ |
||||
if (j >= 0 && j <= 15) |
||||
{ |
||||
return FF1j(X, Y, Z); |
||||
} |
||||
else |
||||
{ |
||||
return FF2j(X, Y, Z); |
||||
} |
||||
} |
||||
|
||||
private static int GGj(int X, int Y, int Z, int j) |
||||
{ |
||||
if (j >= 0 && j <= 15) |
||||
{ |
||||
return GG1j(X, Y, Z); |
||||
} |
||||
else |
||||
{ |
||||
return GG2j(X, Y, Z); |
||||
} |
||||
} |
||||
|
||||
// 逻辑位运算函数
|
||||
private static int FF1j(int X, int Y, int Z) |
||||
{ |
||||
int tmp = X ^ Y ^ Z; |
||||
return tmp; |
||||
} |
||||
|
||||
private static int FF2j(int X, int Y, int Z) |
||||
{ |
||||
int tmp = ((X & Y) | (X & Z) | (Y & Z)); |
||||
return tmp; |
||||
} |
||||
|
||||
private static int GG1j(int X, int Y, int Z) |
||||
{ |
||||
int tmp = X ^ Y ^ Z; |
||||
return tmp; |
||||
} |
||||
|
||||
private static int GG2j(int X, int Y, int Z) |
||||
{ |
||||
int tmp = (X & Y) | (~X & Z); |
||||
return tmp; |
||||
} |
||||
|
||||
private static int P0(int X) |
||||
{ |
||||
int y = rotateLeft(X, 9); |
||||
y = bitCycleLeft(X, 9); |
||||
int z = rotateLeft(X, 17); |
||||
z = bitCycleLeft(X, 17); |
||||
int t = X ^ y ^ z; |
||||
return t; |
||||
} |
||||
|
||||
private static int P1(int X) |
||||
{ |
||||
int t = X ^ bitCycleLeft(X, 15) ^ bitCycleLeft(X, 23); |
||||
return t; |
||||
} |
||||
|
||||
/** |
||||
* 对最后一个分组字节数据padding |
||||
* |
||||
* @param in |
||||
* @param bLen |
||||
* 分组个数 |
||||
* @return |
||||
*/ |
||||
public static byte[] padding(byte[] in, int bLen) |
||||
{ |
||||
int k = 448 - (8 * in.length + 1) % 512; |
||||
if (k < 0) |
||||
{ |
||||
k = 960 - (8 * in.length + 1) % 512; |
||||
} |
||||
k += 1; |
||||
byte[] padd = new byte[k / 8]; |
||||
padd[0] = (byte) 0x80; |
||||
long n = in.length * 8 + bLen * 512; |
||||
byte[] out = new byte[in.length + k / 8 + 64 / 8]; |
||||
int pos = 0; |
||||
System.arraycopy(in, 0, out, 0, in.length); |
||||
pos += in.length; |
||||
System.arraycopy(padd, 0, out, pos, padd.length); |
||||
pos += padd.length; |
||||
byte[] tmp = back(Util.longToBytes(n)); |
||||
System.arraycopy(tmp, 0, out, pos, tmp.length); |
||||
return out; |
||||
} |
||||
|
||||
/** |
||||
* 字节数组逆序 |
||||
* |
||||
* @param in |
||||
* @return |
||||
*/ |
||||
private static byte[] back(byte[] in) |
||||
{ |
||||
byte[] out = new byte[in.length]; |
||||
for (int i = 0; i < out.length; i++) |
||||
{ |
||||
out[i] = in[out.length - i - 1]; |
||||
} |
||||
|
||||
return out; |
||||
} |
||||
|
||||
public static int rotateLeft(int x, int n) |
||||
{ |
||||
return (x << n) | (x >> (32 - n)); |
||||
} |
||||
|
||||
private static int bitCycleLeft(int n, int bitLen) |
||||
{ |
||||
bitLen %= 32; |
||||
byte[] tmp = bigEndianIntToByte(n); |
||||
int byteLen = bitLen / 8; |
||||
int len = bitLen % 8; |
||||
if (byteLen > 0) |
||||
{ |
||||
tmp = byteCycleLeft(tmp, byteLen); |
||||
} |
||||
|
||||
if (len > 0) |
||||
{ |
||||
tmp = bitSmall8CycleLeft(tmp, len); |
||||
} |
||||
|
||||
return bigEndianByteToInt(tmp); |
||||
} |
||||
|
||||
private static byte[] bitSmall8CycleLeft(byte[] in, int len) |
||||
{ |
||||
byte[] tmp = new byte[in.length]; |
||||
int t1, t2, t3; |
||||
for (int i = 0; i < tmp.length; i++) |
||||
{ |
||||
t1 = (byte) ((in[i] & 0x000000ff) << len); |
||||
t2 = (byte) ((in[(i + 1) % tmp.length] & 0x000000ff) >> (8 - len)); |
||||
t3 = (byte) (t1 | t2); |
||||
tmp[i] = (byte) t3; |
||||
} |
||||
|
||||
return tmp; |
||||
} |
||||
|
||||
private static byte[] byteCycleLeft(byte[] in, int byteLen) |
||||
{ |
||||
byte[] tmp = new byte[in.length]; |
||||
System.arraycopy(in, byteLen, tmp, 0, in.length - byteLen); |
||||
System.arraycopy(in, 0, tmp, in.length - byteLen, byteLen); |
||||
return tmp; |
||||
} |
||||
|
||||
public static void main(String[] args) { |
||||
byte[] md = new byte[32]; |
||||
byte[] msg1 = "ererfeiisgod".getBytes(); |
||||
System.out.println(Util.byteToHex(msg1)); |
||||
SM3Digest sm3 = new SM3Digest(); |
||||
sm3.update(msg1, 0, msg1.length); |
||||
sm3.doFinal(md, 0); |
||||
String s = new String(Hex.encode(md)); |
||||
System.out.println(s.toUpperCase()); |
||||
} |
||||
} |
@ -0,0 +1,90 @@ |
||||
package cn.org.landcloud.security.sm3; |
||||
|
||||
import org.bouncycastle.crypto.digests.SM3Digest; |
||||
import org.bouncycastle.util.encoders.Hex; |
||||
|
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.nio.charset.StandardCharsets; |
||||
|
||||
public class SM3Utils { |
||||
|
||||
/** |
||||
* SM3加密,生成16进制SM3字符串<br> |
||||
* |
||||
* @param data 数据 |
||||
* @return SM3字符串 |
||||
*/ |
||||
public static String sm3(byte[] data) { |
||||
byte[] md = new byte[32]; |
||||
SM3Digest sm3 = new SM3Digest(); |
||||
sm3.update(data, 0, data.length); |
||||
sm3.doFinal(md, 0); |
||||
String s = new String(Hex.encode(md)); |
||||
return s.toUpperCase(); |
||||
} |
||||
|
||||
/** |
||||
* SM3加密,生成16进制SM3字符串<br> |
||||
* |
||||
* @param data 数据 |
||||
* @return SM3字符串 |
||||
*/ |
||||
public static String sm3(String data) { |
||||
byte[] md = new byte[32]; |
||||
byte[] msg1 = data.getBytes(StandardCharsets.UTF_8); |
||||
//System.out.println(Util.byteToHex(msg1));
|
||||
SM3Digest sm3 = new SM3Digest(); |
||||
sm3.update(msg1, 0, msg1.length); |
||||
sm3.doFinal(md, 0); |
||||
String s = new String(Hex.encode(md)); |
||||
return s.toUpperCase(); |
||||
} |
||||
|
||||
/** |
||||
* SM3加密,生成16进制SM3字符串<br> |
||||
* |
||||
* @param data 数据 |
||||
* @return SM3字符串 |
||||
*/ |
||||
public static String sm3(InputStream data) throws IOException { |
||||
int bufferLength = 8096; |
||||
final byte[] buffer = new byte[bufferLength]; |
||||
int read; |
||||
byte[] md = new byte[32]; |
||||
SM3Digest sm3Digest = new SM3Digest(); |
||||
while ((read = data.read(buffer, 0, bufferLength)) > -1) { |
||||
sm3Digest.update(buffer, 0, read); |
||||
} |
||||
sm3Digest.doFinal(md, 0); |
||||
String s = new String(Hex.encode(md)); |
||||
return s.toUpperCase(); |
||||
} |
||||
|
||||
/** |
||||
* SM3加密文件,生成16进制SM3字符串<br> |
||||
* |
||||
* @param dataFile 被加密文件 |
||||
* @return SM3字符串 |
||||
*/ |
||||
public static String sm3(File dataFile) throws IOException { |
||||
FileInputStream fis = null; |
||||
try { |
||||
fis = new FileInputStream(dataFile); |
||||
return sm3(fis); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
throw new IOException("文件读取异常"); |
||||
} finally { |
||||
if (fis != null) { |
||||
try { |
||||
fis.close(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,173 @@ |
||||
package cn.org.landcloud.security.sm4; /** |
||||
* Created by $(USER) on $(DATE) |
||||
*/ |
||||
|
||||
import java.io.IOException; |
||||
import java.util.regex.Matcher; |
||||
import java.util.regex.Pattern; |
||||
|
||||
import cn.org.landcloud.security.Base64; |
||||
import cn.org.landcloud.security.Util; |
||||
|
||||
public class SM4Utils { |
||||
// private String secretKey = "";
|
||||
// private String iv = "";
|
||||
// private boolean hexString = false;
|
||||
|
||||
public String secretKey = ""; |
||||
public String iv = ""; |
||||
public boolean hexString = false; |
||||
|
||||
public SM4Utils() { |
||||
} |
||||
|
||||
|
||||
public String encryptData_ECB(String plainText) { |
||||
try { |
||||
SM4_Context ctx = new SM4_Context(); |
||||
ctx.isPadding = true; |
||||
ctx.mode = SM4.SM4_ENCRYPT; |
||||
|
||||
byte[] keyBytes; |
||||
if (hexString) { |
||||
keyBytes = Util.hexStringToBytes(secretKey); |
||||
} else { |
||||
//keyBytes = secretKey.getBytes();
|
||||
keyBytes = Util.hexStringToBytes(secretKey); |
||||
} |
||||
|
||||
SM4 sm4 = new SM4(); |
||||
sm4.sm4_setkey_enc(ctx, keyBytes); |
||||
byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainText.getBytes("UTF-8")); |
||||
return Util.byteToHex(encrypted); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public String decryptData_ECB(String cipherText) { |
||||
try { |
||||
byte[] encrypted = Util.hexToByte(cipherText); |
||||
cipherText=Base64.encode(encrypted);; |
||||
//cipherText = new BASE64Encoder().encode(encrypted);
|
||||
if (cipherText != null && cipherText.trim().length() > 0) { |
||||
Pattern p = Pattern.compile("\\s*|\t|\r|\n"); |
||||
Matcher m = p.matcher(cipherText); |
||||
cipherText = m.replaceAll(""); |
||||
} |
||||
|
||||
SM4_Context ctx = new SM4_Context(); |
||||
ctx.isPadding = true; |
||||
ctx.mode = SM4.SM4_DECRYPT; |
||||
|
||||
byte[] keyBytes; |
||||
if (hexString) { |
||||
keyBytes = Util.hexStringToBytes(secretKey); |
||||
} else { |
||||
keyBytes = secretKey.getBytes(); |
||||
} |
||||
|
||||
SM4 sm4 = new SM4(); |
||||
sm4.sm4_setkey_dec(ctx, keyBytes); |
||||
byte[] decrypted = sm4.sm4_crypt_ecb(ctx, Base64.decode(cipherText)); |
||||
//byte[] decrypted = sm4.sm4_crypt_ecb(ctx, new BASE64Decoder().decodeBuffer(cipherText));
|
||||
return new String(decrypted, "UTF-8"); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public String encryptData_CBC(String plainText) { |
||||
try { |
||||
SM4_Context ctx = new SM4_Context(); |
||||
ctx.isPadding = true; |
||||
ctx.mode = SM4.SM4_ENCRYPT; |
||||
|
||||
byte[] keyBytes; |
||||
byte[] ivBytes; |
||||
if (hexString) { |
||||
keyBytes = Util.hexStringToBytes(secretKey); |
||||
ivBytes = Util.hexStringToBytes(iv); |
||||
} else { |
||||
keyBytes = secretKey.getBytes(); |
||||
ivBytes = iv.getBytes(); |
||||
} |
||||
|
||||
SM4 sm4 = new SM4(); |
||||
sm4.sm4_setkey_enc(ctx, keyBytes); |
||||
byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainText.getBytes("UTF-8")); |
||||
return Util.byteToHex(encrypted); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public String decryptData_CBC(String cipherText) { |
||||
try { |
||||
byte[] encrypted = Util.hexToByte(cipherText); |
||||
cipherText=Base64.encode(encrypted);; |
||||
//cipherText = new BASE64Encoder().encode(encrypted);
|
||||
if (cipherText != null && cipherText.trim().length() > 0) { |
||||
Pattern p = Pattern.compile("\\s*|\t|\r|\n"); |
||||
Matcher m = p.matcher(cipherText); |
||||
cipherText = m.replaceAll(""); |
||||
} |
||||
SM4_Context ctx = new SM4_Context(); |
||||
ctx.isPadding = true; |
||||
ctx.mode = SM4.SM4_DECRYPT; |
||||
|
||||
byte[] keyBytes; |
||||
byte[] ivBytes; |
||||
if (hexString) { |
||||
keyBytes = Util.hexStringToBytes(secretKey); |
||||
ivBytes = Util.hexStringToBytes(iv); |
||||
} else { |
||||
keyBytes = secretKey.getBytes(); |
||||
ivBytes = iv.getBytes(); |
||||
} |
||||
|
||||
SM4 sm4 = new SM4(); |
||||
sm4.sm4_setkey_dec(ctx, keyBytes); |
||||
//byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, new BASE64Decoder().decodeBuffer(cipherText));
|
||||
byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Base64.decode(cipherText)); |
||||
/*String text = new String(decrypted, "UTF-8"); |
||||
return text.substring(0,text.length()-1);*/ |
||||
return new String(decrypted, "UTF-8"); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public static void main(String[] args) throws IOException { |
||||
String plainText = "I Love You Every Day"; |
||||
String s = Util.byteToHex(plainText.getBytes()); |
||||
System.out.println("原文" + s); |
||||
SM4Utils sm4 = new SM4Utils(); |
||||
//sm4.secretKey = "JeF8U9wHFOMfs2Y8";
|
||||
sm4.secretKey = "64EC7C763AB7BF64E2D75FF83A319918"; |
||||
sm4.hexString = true; |
||||
|
||||
System.out.println("ECB模式加密"); |
||||
String cipherText = sm4.encryptData_ECB(plainText); |
||||
System.out.println("密文: " + cipherText); |
||||
System.out.println(""); |
||||
|
||||
String plainText2 = sm4.decryptData_ECB(cipherText); |
||||
System.out.println("明文: " + plainText2); |
||||
System.out.println(""); |
||||
|
||||
System.out.println("CBC模式加密"); |
||||
sm4.iv = "31313131313131313131313131313131"; |
||||
String cipherText2 = sm4.encryptData_CBC(plainText); |
||||
System.out.println("加密密文: " + cipherText2); |
||||
System.out.println(""); |
||||
|
||||
String plainText3 = sm4.decryptData_CBC(cipherText2); |
||||
System.out.println("解密明文: " + plainText3); |
||||
|
||||
} |
||||
} |
@ -0,0 +1,19 @@ |
||||
package cn.org.landcloud.security.sm4; |
||||
|
||||
/** |
||||
* Created by $(USER) on $(DATE) |
||||
*/ |
||||
public class SM4_Context { |
||||
public int mode; |
||||
|
||||
public long[] sk; |
||||
|
||||
public boolean isPadding; |
||||
|
||||
public SM4_Context() |
||||
{ |
||||
this.mode = 1; |
||||
this.isPadding = true; |
||||
this.sk = new long[32]; |
||||
} |
||||
} |
@ -0,0 +1,131 @@ |
||||
package cn.org.landcloud.security.test; |
||||
|
||||
import org.bouncycastle.crypto.digests.SM3Digest; |
||||
import org.bouncycastle.util.encoders.Hex; |
||||
import org.junit.Test; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
import cn.org.landcloud.security.sm2.SM2EncDecUtils; |
||||
import cn.org.landcloud.security.sm2.SM2SignVO; |
||||
import cn.org.landcloud.security.sm2.SM2SignVerUtils; |
||||
|
||||
public class SecurityTest { |
||||
|
||||
@Test |
||||
public void sm2sign() throws Exception { |
||||
String src = "0653F3748DFD938FE83935800FF3F526B85C30C2331DD56FCB1794AA99F2A416"; |
||||
String text = "这是一段明文"; |
||||
byte[] sourceData = text.getBytes(); |
||||
//String publicKey ="FA05C51AD1162133DFDF862ECA5E4A481B52FB37FF83E53D45FD18BBD6F32668A92C4692EEB305684E3B9D4ACE767F91D5D108234A9F07936020A92210BA9447";
|
||||
//String privatekey = "5EB4DF17021CC719B678D970C620690A11B29C8357D71FA4FF9BF7FB6D89767A";
|
||||
String publicKey = "042780f0963a428a7b030ac1c14a90b967bf365f5394ebf1f0ca1598d4d9bece4fdfa05ba043817fef68bef497088e3992362ce55b1858444fa5a3e00c5042b207"; |
||||
String privatekey = "73e83d33d95274eeeb23f01834d02fe920b4afece377410435698dfdf1d84203"; |
||||
|
||||
SM2SignVO sign = SM2SignVerUtils.Sign2SM2(Util.hexStringToBytes(privatekey), Util.hexToByte(src)); |
||||
System.out.println("R:"+sign.sign_r); |
||||
System.out.println("S:"+sign.sign_s); |
||||
//验签硬加密的串
|
||||
String signYJ = "54720652E5EE53D14F338A03EDAC10E7F93D877EC2168F9287810807D02D2409F3EEE542638AD0B204BC3C8F93EDBCFBE87DEEFB07C0B36F34508AB49B6F90EF"; |
||||
SM2SignVO verify = SM2SignVerUtils.VerifySignSM2(Util.hexStringToBytes(publicKey), Util.hexToByte(src), Util.hexToByte(SecurityTestAll.SM2SignHardToSoft(signYJ))); |
||||
System.err.println("验签结果" + verify.isVerify()); |
||||
} |
||||
|
||||
@Test |
||||
public void sm2sign2() throws Exception { |
||||
String src = "32472f598b61ea4ff28f54b00f12ca0a8c1596e2867c5cce4afcb19ee93c2cde"; |
||||
String text = "这是一段明文"; |
||||
byte[] sourceData = text.getBytes(); |
||||
//String publicKey ="FA05C51AD1162133DFDF862ECA5E4A481B52FB37FF83E53D45FD18BBD6F32668A92C4692EEB305684E3B9D4ACE767F91D5D108234A9F07936020A92210BA9447";
|
||||
//String privatekey = "5EB4DF17021CC719B678D970C620690A11B29C8357D71FA4FF9BF7FB6D89767A";
|
||||
String publicKey = "0485B52403AEB742F952EFF7200BDBA0A399F0971FEB0EAA0CBE00A1A5EE922A34A24BD9CD2EA740B84290838A862E432BD9BBC0CD0659FD6D172CD1871CD76068"; |
||||
String privatekey = "62329467E71E70960C7A479C03CA7FC0A2BE92E000240C4F4080F0B2437C536D"; |
||||
|
||||
SM2SignVO sign = SM2SignVerUtils.Sign2SM2(Util.hexStringToBytes(privatekey), Util.hexToByte(src)); |
||||
System.out.println("R:"+sign.sign_r); |
||||
System.out.println("S:"+sign.sign_s); |
||||
//验签硬加密的串
|
||||
String signYJ = "233fabe6f81002fbee8c69d9561114d99e0640ecf27d63561d850d77ac76ee5f5d0530bd6eca60e960784f9ad883b77dcfa3c8b274918034faf509faeee2e5ea"; |
||||
SM2SignVO verify = SM2SignVerUtils.VerifySignSM2(Util.hexStringToBytes(publicKey), Util.hexToByte(src), Util.hexToByte(SecurityTestAll.SM2SignHardToSoft(signYJ))); |
||||
System.err.println("验签结果" + verify.isVerify()); |
||||
} |
||||
|
||||
@Test |
||||
public void sm2enc() throws IOException { |
||||
String plainText = "ILoveYou11"; |
||||
//SM3测试
|
||||
//生成密钥对
|
||||
//generateKeyPair();
|
||||
byte[] sourceData = plainText.getBytes(); |
||||
|
||||
//下面的秘钥可以使用generateKeyPair()生成的秘钥内容
|
||||
// 国密规范正式私钥
|
||||
//String prik = "3690655E33D5EA3D9A4AE1A1ADD766FDEA045CDEAA43A9206FB8C430CEFE0D94";
|
||||
// 国密规范正式公钥
|
||||
//String pubk = "04F6E0C3345AE42B51E06BF50B98834988D54EBC7460FE135A48171BC0629EAE205EEDE253A530608178A98F1E19BB737302813BA39ED3FA3C51639D7A20C7391A";
|
||||
|
||||
String prik = "4cf170068e9c47ebdb521fb9fc62c4a55a5773fb9da33b0acf8129e28d09d205"; |
||||
String pubk = "04aabda53043e8dcb86d42f690b61a4db869821dadf9f851ec3c5c43d0c8f95a6677fdba984afc3bb010a8436b1d17cefc2011a34e01e9e801124d29ffa928d803"; |
||||
String publicKey = "04BB34D657EE7E8490E66EF577E6B3CEA28B739511E787FB4F71B7F38F241D87F18A5A93DF74E90FF94F4EB907F271A36B295B851F971DA5418F4915E2C1A23D6E"; |
||||
String privatekey = "0B1CE43098BC21B8E82B5C065EDB534CB86532B1900A49D49F3C53762D2997FA"; |
||||
prik = privatekey; |
||||
pubk = publicKey; |
||||
System.out.println("加密: "); |
||||
String cipherText = SM2EncDecUtils.encrypt(Util.hexToByte(pubk), sourceData); |
||||
//cipherText = "0452ba81cf5119c9f29c81c2be9c4a49ad8c0a33ed899b60548d21a62971a8e994cafc0e9fbc710a0a220b055804bb890833b50ac04ec4e130a5db75338c0c1d49a52a6d373076a5db370564a5cebb5300f79877003c52adf49dac16370e51e14e0754110547bb3b";
|
||||
System.out.println(cipherText); |
||||
System.out.println("解密: "); |
||||
plainText = new String(SM2EncDecUtils.decrypt(Util.hexToByte(prik), Util.hexToByte(cipherText))); |
||||
System.out.println(plainText); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void sm3() { |
||||
byte[] md = new byte[32]; |
||||
byte[] msg1 = "ererfeiisgod".getBytes(); |
||||
System.out.println(Util.byteToHex(msg1)); |
||||
SM3Digest sm3 = new SM3Digest(); |
||||
sm3.update(msg1, 0, msg1.length); |
||||
sm3.doFinal(md, 0); |
||||
String s = new String(Hex.encode(md)); |
||||
System.out.println(s.toUpperCase()); |
||||
} |
||||
|
||||
@Test |
||||
public void sm4() throws IOException { |
||||
/*String plainText = "我爱中国啊1我爱我我他2"; |
||||
String s = Util.byteToHex(plainText.getBytes()); |
||||
System.out.println("原文" + s); |
||||
SM4Utils sm4 = new SM4Utils(); |
||||
//sm4.secretKey = "JeF8U9wHFOMfs2Y8";
|
||||
sm4.secretKey = "E76E9B4E0245BC56FCE4E29B208C6A50"; |
||||
sm4.hexString = true; |
||||
|
||||
System.out.println("ECB模式加密"); |
||||
String cipherText = sm4.encryptData_ECB(plainText); |
||||
System.out.println("密文: " + cipherText); |
||||
System.out.println(""); |
||||
|
||||
plainText = sm4.decryptData_ECB(cipherText); |
||||
System.out.println("明文: " + plainText); |
||||
System.out.println(""); |
||||
|
||||
System.out.println("CBC模式加密"); |
||||
sm4.iv = "30303030303030303030303030303030"; |
||||
cipherText = sm4.encryptData_CBC(plainText); |
||||
System.out.println("加密密文: " + cipherText); |
||||
System.out.println(""); |
||||
|
||||
plainText = sm4.decryptData_CBC(cipherText); |
||||
System.out.println("解密明文: " + plainText);*/ |
||||
|
||||
} |
||||
|
||||
|
||||
public static void main(String[] args) throws IOException { |
||||
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,219 @@ |
||||
package cn.org.landcloud.security.test; |
||||
|
||||
import org.bouncycastle.asn1.ASN1EncodableVector; |
||||
import org.bouncycastle.asn1.ASN1Integer; |
||||
import org.bouncycastle.asn1.DERSequence; |
||||
import org.bouncycastle.crypto.digests.SM3Digest; |
||||
import org.bouncycastle.util.encoders.Hex; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.UUID; |
||||
|
||||
import cn.org.landcloud.security.Util; |
||||
import cn.org.landcloud.security.sm2.SM2EncDecUtils; |
||||
import cn.org.landcloud.security.sm2.SM2KeyVO; |
||||
import cn.org.landcloud.security.sm2.SM2SignVO; |
||||
import cn.org.landcloud.security.sm2.SM2SignVerUtils; |
||||
import cn.org.landcloud.security.sm4.SM4Utils; |
||||
|
||||
public class SecurityTestAll { |
||||
//SM2公钥编码格式
|
||||
//HardPubKey:3059301306072A8648CE3D020106082A811CCF5501822D03420004+X+Y
|
||||
//SoftPubKey:04+X+Y
|
||||
public static final String SM2PubHardKeyHead = "3059301306072A8648CE3D020106082A811CCF5501822D034200"; |
||||
//SM2加密 密文区别:软加密多了04
|
||||
//SM2加密机签名编码格式
|
||||
//HardSign:R+S
|
||||
//public static final String SM2PubHardKeyHead="3059301306072A8648CE3D020106082A811CCF5501822D034200";
|
||||
//private final String SM4_CBC_IV="";
|
||||
//private final String SM2="";
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception { |
||||
System.out.println("--产生SM2秘钥--:"); |
||||
SM2KeyVO sm2KeyVO = generateSM2Key(); |
||||
System.out.println("公钥:" + sm2KeyVO.getPubHexInSoft()); |
||||
System.out.println("私钥:" + sm2KeyVO.getPriHexInSoft()); |
||||
//数据加密
|
||||
System.out.println("--测试加密开始--"); |
||||
String src = "I Love You"; |
||||
System.out.println("原文UTF-8转hex:" + Util.byteToHex(src.getBytes())); |
||||
String SM2Enc = SM2Enc(sm2KeyVO.getPubHexInSoft(), src); |
||||
System.out.println("加密:"); |
||||
System.out.println("密文:" + SM2Enc); |
||||
String SM2Dec = SM2Dec(sm2KeyVO.getPriHexInSoft(), SM2Enc); |
||||
System.out.println("解密:" + SM2Dec); |
||||
System.out.println("--测试加密结束--"); |
||||
|
||||
System.out.println("--测试SM2签名--"); |
||||
System.out.println("原文hex:" + Util.byteToHex(src.getBytes())); |
||||
String s5 = Util.byteToHex(src.getBytes()); |
||||
|
||||
System.out.println("签名测试开始:"); |
||||
SM2SignVO sign = genSM2Signature(sm2KeyVO.getPriHexInSoft(), s5); |
||||
System.out.println("软加密签名结果:" + sign.getSm2_signForSoft()); |
||||
System.out.println("加密机签名结果:" + sign.getSm2_signForHard()); |
||||
//System.out.println("转签名测试:"+SM2SignHardToSoft(sign.getSm2_signForHard()));
|
||||
System.out.println("验签1,软件加密方式:"); |
||||
boolean b = verifySM2Signature(sm2KeyVO.getPubHexInSoft(), s5, sign.getSm2_signForSoft()); |
||||
System.out.println("软件加密方式验签结果:" + b); |
||||
System.out.println("验签2,硬件加密方式:"); |
||||
String sm2_signForHard = sign.getSm2_signForHard(); |
||||
System.out.println("签名R:"+sign.sign_r); |
||||
System.out.println("签名S:"+sign.sign_s); |
||||
//System.out.println("硬:"+sm2_signForHard);
|
||||
b = verifySM2Signature(sm2KeyVO.getPubHexInSoft(), s5, SM2SignHardToSoft(sign.getSm2_signForHard())); |
||||
System.out.println("硬件加密方式验签结果:" + b); |
||||
if (!b) { |
||||
throw new RuntimeException(); |
||||
} |
||||
System.out.println("--签名测试结束--"); |
||||
|
||||
System.out.println("--SM3摘要测试--"); |
||||
String s = generateSM3HASH(src); |
||||
System.out.println("hash:"+s); |
||||
System.out.println("--SM3摘要结束--"); |
||||
|
||||
System.out.println("--生成SM4秘钥--"); |
||||
String sm4Key = generateSM4Key(); |
||||
System.out.println("sm4Key:"+sm4Key); |
||||
System.out.println("--生成SM4结束--"); |
||||
System.out.println("--SM4的CBC加密--"); |
||||
String s1 = SM4EncForCBC(sm4Key, src); |
||||
System.out.println("密文:"+s1); |
||||
System.out.println("CBC解密"); |
||||
String s2 = SM4DecForCBC(sm4Key, s1); |
||||
System.out.println("解密结果:"+s2); |
||||
System.out.println("--ECB加密--"); |
||||
String s3 = SM4EncForECB(sm4Key, src); |
||||
System.out.println("ECB密文:"+s3); |
||||
System.out.println("ECB解密"); |
||||
String s4 = SM4DecForECB(sm4Key, s3); |
||||
System.out.println("ECB解密结果:"+s4); |
||||
} |
||||
|
||||
//SM2公钥soft和Hard转换
|
||||
public static String SM2PubKeySoftToHard(String softKey) { |
||||
return SM2PubHardKeyHead + softKey; |
||||
} |
||||
|
||||
//SM2公钥Hard和soft转换
|
||||
public static String SM2PubKeyHardToSoft(String hardKey) { |
||||
return hardKey.replaceFirst(SM2PubHardKeyHead, ""); |
||||
} |
||||
|
||||
//产生非对称秘钥
|
||||
public static SM2KeyVO generateSM2Key() throws IOException { |
||||
SM2KeyVO sm2KeyVO = SM2EncDecUtils.generateKeyPair(); |
||||
return sm2KeyVO; |
||||
} |
||||
|
||||
//公钥加密
|
||||
public static String SM2Enc(String pubKey, String src) throws IOException { |
||||
String encrypt = SM2EncDecUtils.encrypt(Util.hexStringToBytes(pubKey), src.getBytes()); |
||||
//删除04
|
||||
encrypt=encrypt.substring(2,encrypt.length()); |
||||
return encrypt; |
||||
} |
||||
|
||||
//私钥解密
|
||||
public static String SM2Dec(String priKey, String encryptedData) throws IOException { |
||||
//填充04
|
||||
encryptedData="04"+encryptedData; |
||||
byte[] decrypt = SM2EncDecUtils.decrypt(Util.hexStringToBytes(priKey), Util.hexStringToBytes(encryptedData)); |
||||
return new String(decrypt); |
||||
} |
||||
|
||||
//私钥签名,参数二:原串必须是hex!!!!因为是直接用于计算签名的,可能是SM3串,也可能是普通串转Hex
|
||||
public static SM2SignVO genSM2Signature(String priKey, String sourceData) throws Exception { |
||||
SM2SignVO sign = SM2SignVerUtils.Sign2SM2(Util.hexToByte(priKey), Util.hexToByte(sourceData)); |
||||
return sign; |
||||
} |
||||
|
||||
//公钥验签,参数二:原串必须是hex!!!!因为是直接用于计算签名的,可能是SM3串,也可能是普通串转Hex
|
||||
public static boolean verifySM2Signature(String pubKey, String sourceData, String hardSign) { |
||||
SM2SignVO verify = SM2SignVerUtils.VerifySignSM2(Util.hexStringToBytes(pubKey), Util.hexToByte(sourceData), Util.hexToByte(hardSign)); |
||||
return verify.isVerify(); |
||||
} |
||||
|
||||
//SM2签名Hard转soft
|
||||
public static String SM2SignHardToSoft(String hardSign) { |
||||
byte[] bytes = Util.hexToByte(hardSign); |
||||
byte[] r = new byte[bytes.length / 2]; |
||||
byte[] s = new byte[bytes.length / 2]; |
||||
System.arraycopy(bytes, 0, r, 0, bytes.length / 2); |
||||
System.arraycopy(bytes, bytes.length / 2, s, 0, bytes.length / 2); |
||||
ASN1Integer d_r = new ASN1Integer(Util.byteConvertInteger(r)); |
||||
ASN1Integer d_s = new ASN1Integer(Util.byteConvertInteger(s)); |
||||
ASN1EncodableVector v2 = new ASN1EncodableVector(); |
||||
v2.add(d_r); |
||||
v2.add(d_s); |
||||
DERSequence sign = new DERSequence(v2); |
||||
|
||||
String result = null; |
||||
try { |
||||
result = Util.byteToHex(sign.getEncoded()); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
throw new RuntimeException(e); |
||||
} |
||||
//SM2加密机转软加密编码格式
|
||||
//return SM2SignHardKeyHead+hardSign.substring(0, hardSign.length()/2)+SM2SignHardKeyMid+hardSign.substring(hardSign.length()/2);
|
||||
return result; |
||||
} |
||||
|
||||
//摘要计算
|
||||
public static String generateSM3HASH(String src) { |
||||
byte[] md = new byte[32]; |
||||
byte[] msg1 = src.getBytes(); |
||||
//System.out.println(Util.byteToHex(msg1));
|
||||
SM3Digest sm3 = new SM3Digest(); |
||||
sm3.update(msg1, 0, msg1.length); |
||||
sm3.doFinal(md, 0); |
||||
String s = new String(Hex.encode(md)); |
||||
return s.toUpperCase(); |
||||
} |
||||
|
||||
//产生对称秘钥
|
||||
public static String generateSM4Key() { |
||||
return UUID.randomUUID().toString().replace("-", ""); |
||||
} |
||||
|
||||
|
||||
//对称秘钥加密(CBC)
|
||||
public static String SM4EncForCBC(String key,String text) { |
||||
SM4Utils sm4 = new SM4Utils(); |
||||
sm4.secretKey = key; |
||||
sm4.hexString = true; |
||||
sm4.iv = "31313131313131313131313131313131"; |
||||
String cipherText = sm4.encryptData_CBC(text); |
||||
return cipherText; |
||||
} |
||||
|
||||
//对称秘钥解密(CBC)
|
||||
public static String SM4DecForCBC(String key,String text) { |
||||
SM4Utils sm4 = new SM4Utils(); |
||||
sm4.secretKey = key; |
||||
sm4.hexString = true; |
||||
sm4.iv = "31313131313131313131313131313131"; |
||||
String plainText = sm4.decryptData_CBC(text); |
||||
return plainText; |
||||
} |
||||
//对称秘钥加密(ECB)
|
||||
public static String SM4EncForECB(String key,String text) { |
||||
SM4Utils sm4 = new SM4Utils(); |
||||
sm4.secretKey = key; |
||||
sm4.hexString = true; |
||||
String cipherText = sm4.encryptData_ECB(text); |
||||
return cipherText; |
||||
} |
||||
//对称秘钥解密(ECB)
|
||||
public static String SM4DecForECB(String key,String text) { |
||||
SM4Utils sm4 = new SM4Utils(); |
||||
sm4.secretKey = key; |
||||
sm4.hexString = true; |
||||
String plainText = sm4.decryptData_ECB(text); |
||||
return plainText; |
||||
} |
||||
|
||||
} |