780 lines
28 KiB
Java
780 lines
28 KiB
Java
package com.sunyard.sge.database;
|
|
|
|
import com.sun.jna.ptr.IntByReference;
|
|
import com.sunyard.SydApiException;
|
|
import com.sunyard.proto.Util;
|
|
import com.sunyard.sge.bytes.BytesUtil;
|
|
import com.sunyard.sge.plus.ConnectHandlerManager;
|
|
import com.sunyard.sge.plus.SydLibrary;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
import java.util.concurrent.Callable;
|
|
import java.util.concurrent.ExecutionException;
|
|
import java.util.concurrent.FutureTask;
|
|
|
|
import static com.sunyard.sge.database.SydApiBaseFunction.toBoolArray;
|
|
import static com.sunyard.sge.database.SydApiBaseFunction.toIntArray;
|
|
import static com.sunyard.sge.database.SydApiConfig.BATCH_SIZE;
|
|
|
|
/**
|
|
* 长连接的真正执行过程转发到长连接线程池中执行。
|
|
*/
|
|
public class SydApiLongLinkWrap implements SydApi {
|
|
|
|
private SydApiBuilder builder;
|
|
|
|
public SydApiLongLinkWrap(SydApiBuilder builder) {
|
|
this.builder = builder;
|
|
}
|
|
|
|
@Override
|
|
public SydApi SYD_Short_Connect_Ex(String[] pcIpList, int[] iPortList, int iConnectTimeOut, int iDealTimeOut) {
|
|
throw new UnsupportedOperationException("此对象为长连接专用");
|
|
}
|
|
|
|
@Override
|
|
public void SYD_Disconnect_Ex() {
|
|
// pass
|
|
}
|
|
|
|
@Override
|
|
public String SYD_SM3_Hash_ShortData(byte[] pcData) {
|
|
FutureTask<String> task = builder.getLongLinkWorks().fTask(new Callable<String>() {
|
|
@Override
|
|
public String call() throws Exception {
|
|
return builder.get().SYD_SM3_Hash_ShortData(pcData);
|
|
}
|
|
});
|
|
try {
|
|
return task.get();
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public LongDataReturn<String, String> SYD_SM3_Hash_LongData(byte[] pcData, int iPkgNum, String pcProcData) {
|
|
FutureTask<LongDataReturn<String, String>> task = builder.getLongLinkWorks().fTask(new Callable<LongDataReturn<String, String>>() {
|
|
@Override
|
|
public LongDataReturn<String, String> call() throws Exception {
|
|
return builder.get().SYD_SM3_Hash_LongData(pcData, iPkgNum, pcProcData);
|
|
}
|
|
});
|
|
try {
|
|
return task.get();
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public byte[] SYD_SM4_ShortData(int iKeyIndex, byte[] pcData, int iFlag) {
|
|
FutureTask<byte[]> task = builder.getLongLinkWorks().fTask(new Callable<byte[]>() {
|
|
@Override
|
|
public byte[] call() throws Exception {
|
|
return builder.get().SYD_SM4_ShortData(iKeyIndex, pcData, iFlag);
|
|
}
|
|
});
|
|
try {
|
|
return task.get();
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public byte[] SYD_SM4_LongData(int iKeyIndex, byte[] pcData, int iPkgNum, int iFlag) {
|
|
FutureTask<byte[]> task = builder.getLongLinkWorks().fTask(new Callable<byte[]>() {
|
|
@Override
|
|
public byte[] call() throws Exception {
|
|
return builder.get().SYD_SM4_LongData(iKeyIndex, pcData, iPkgNum, iFlag);
|
|
}
|
|
});
|
|
try {
|
|
return task.get();
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
public LongDataReturn<String, String> SYD_SM4Mac_LongData(int iKeyIndex, byte[] pcData, int iPkgNum, String pcProcData) {
|
|
FutureTask<LongDataReturn<String, String>> task = builder.getLongLinkWorks().fTask(new Callable<LongDataReturn<String, String>>() {
|
|
@Override
|
|
public LongDataReturn<String, String> call() throws Exception {
|
|
return builder.get().SYD_SM4Mac_LongData(iKeyIndex, pcData, iPkgNum, pcProcData);
|
|
}
|
|
});
|
|
try {
|
|
return task.get();
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public LongDataReturn<String, Boolean> SYD_SM4Mac_LongData(int iKeyIndex, byte[] pcData, int iPkgNum, String pcProcData, String pcMac) {
|
|
FutureTask<LongDataReturn<String, Boolean>> task = builder.getLongLinkWorks().fTask(new Callable<LongDataReturn<String, Boolean>>() {
|
|
@Override
|
|
public LongDataReturn<String, Boolean> call() throws Exception {
|
|
return builder.get().SYD_SM4Mac_LongData(iKeyIndex, pcData, iPkgNum, pcProcData, pcMac);
|
|
}
|
|
});
|
|
try {
|
|
return task.get();
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public byte[] SYD_SM4Mac_ShortData(int iKeyIndex, byte[] pcData) {
|
|
FutureTask<byte[]> task = builder.getLongLinkWorks().fTask(new Callable<byte[]>() {
|
|
@Override
|
|
public byte[] call() throws Exception {
|
|
return builder.get().SYD_SM4Mac_ShortData(iKeyIndex, pcData);
|
|
}
|
|
});
|
|
try {
|
|
return task.get();
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean SYD_SM4Mac_ShortData(int iKeyIndex, byte[] pcData, byte[] pcMac) {
|
|
FutureTask<Boolean> task = builder.getLongLinkWorks().fTask(new Callable<Boolean>() {
|
|
@Override
|
|
public Boolean call() throws Exception {
|
|
return builder.get().SYD_SM4Mac_ShortData(iKeyIndex, pcData, pcMac);
|
|
}
|
|
});
|
|
try {
|
|
return task.get();
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
private DataAndMac SYD_SM4_AllInOne(int iEncKeyIndex, int iMacKeyIndex, byte[] pcData){
|
|
try {
|
|
FutureTask<byte[]> taskEnc = builder.getLongLinkWorks().fTask(new Callable<byte[]>() {
|
|
@Override
|
|
public byte[] call() throws Exception {
|
|
return builder.get().SYD_SM4_ShortData(iEncKeyIndex, pcData, Consts.ECB_ENC);
|
|
}
|
|
});
|
|
|
|
byte[] enData = taskEnc.get();
|
|
|
|
FutureTask<byte[]> taskMac = builder.getLongLinkWorks().fTask(new Callable<byte[]>() {
|
|
@Override
|
|
public byte[] call() throws Exception {
|
|
return builder.get().SYD_SM4Mac_ShortData(iMacKeyIndex, enData);
|
|
}
|
|
});
|
|
|
|
byte[] mac = taskMac.get();
|
|
return new DataAndMac(enData, mac);
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public DataAndMac SYD_SM4_EncryptAndMac_ShortData(int iEncKeyIndex, int iMacKeyIndex, byte[] pcData) {
|
|
try {
|
|
if ( ! ConnectHandlerManager.isInited() ) {
|
|
throw new SydApiException(-1);
|
|
}
|
|
|
|
int enLen = BytesUtil.calculatePaddedLength(pcData.length);
|
|
byte[] encData = new byte[enLen];
|
|
byte[] mac = new byte[16];
|
|
IntByReference encDataLen = new IntByReference(encData.length);
|
|
|
|
int i = SydLibrary.INSTANCE.SYD_SM4_Encrypt_Mac_ShortData(
|
|
ConnectHandlerManager.getHandler(),
|
|
iEncKeyIndex,
|
|
iMacKeyIndex,
|
|
pcData,
|
|
pcData.length,
|
|
encData,
|
|
encDataLen,
|
|
mac
|
|
);
|
|
|
|
if ( 0 == i ){
|
|
byte[] data = new byte[encDataLen.getValue()];
|
|
if( data.length == encData.length ) {
|
|
data = encData;
|
|
} else {
|
|
System.arraycopy(encData, 0, data, 0, data.length);
|
|
}
|
|
|
|
return new DataAndMac(data, mac);
|
|
} else {
|
|
throw new SydApiException(i);
|
|
}
|
|
|
|
// return SYD_SM4_AllInOne(iEncKeyIndex, iMacKeyIndex, pcData);
|
|
|
|
// // 线程池忙, 使用单线程计算
|
|
// if( builder.getLongLinkWorks().threadPoolIsBusy() ) {
|
|
// return SYD_SM4_AllInOne(iEncKeyIndex, iMacKeyIndex, pcData);
|
|
// }
|
|
//
|
|
// // 线程池不忙,使用并发计算
|
|
//
|
|
// // 将pcData拆分为两半,第一半16字节对齐
|
|
// int halfLength = pcData.length / 2;
|
|
// int alignedLength = (halfLength + 15) & ~15; // 向上取整到16的倍数
|
|
// alignedLength = Math.min(alignedLength, pcData.length); // 不超过原始数据长度
|
|
// if (alignedLength < 16) {
|
|
// throw new IllegalArgumentException("数据长度不足16字节,无法对齐");
|
|
// }
|
|
//
|
|
//
|
|
// byte[] firstHalf = Arrays.copyOfRange(pcData, 0, alignedLength);
|
|
// byte[] secondHalf = Arrays.copyOfRange(pcData, alignedLength, pcData.length);
|
|
//
|
|
//
|
|
// FutureTask<byte[]> taskEnc1 = builder.getLongLinkWorks().fTask(new Callable<byte[]>() {
|
|
// @Override
|
|
// public byte[] call() throws Exception {
|
|
// return builder.get().SYD_SM4_LongData( iEncKeyIndex, firstHalf, 1, Consts.ECB_ENC);
|
|
// }
|
|
// });
|
|
// FutureTask<byte[]> taskEnc2 = builder.getLongLinkWorks().fTask(new Callable<byte[]>() {
|
|
// @Override
|
|
// public byte[] call() throws Exception {
|
|
// return builder.get().SYD_SM4_LongData( iEncKeyIndex, secondHalf, 3, Consts.ECB_ENC);
|
|
// }
|
|
// });
|
|
//
|
|
// byte[] enData1 = taskEnc1.get();
|
|
// FutureTask<LongDataReturn<String, String>> taskMac = builder.getLongLinkWorks().fTask(new Callable< LongDataReturn<String, String>>() {
|
|
// @Override
|
|
// public LongDataReturn<String, String> call() throws Exception {
|
|
// return builder.get().SYD_SM4Mac_LongData(iMacKeyIndex, enData1, 1, null);
|
|
// }
|
|
// });
|
|
//
|
|
// byte[] enData2 = taskEnc2.get();
|
|
// LongDataReturn<String, String> macProc = taskMac.get();
|
|
// FutureTask<LongDataReturn<String, String>> taskMac2 = builder.getLongLinkWorks().fTask(new Callable<LongDataReturn<String, String>>() {
|
|
// @Override
|
|
// public LongDataReturn<String, String> call() throws Exception {
|
|
// return builder.get().SYD_SM4Mac_LongData(iMacKeyIndex, enData2, 3, macProc.getProcData());
|
|
// }
|
|
// });
|
|
// LongDataReturn<String, String> mac = taskMac.get();
|
|
//
|
|
// // 合并密文
|
|
// byte[] enData = new byte[enData1.length + enData2.length];
|
|
// System.arraycopy(enData1, 0, enData, 0, enData1.length);
|
|
// System.arraycopy(enData2, 0, enData, enData1.length, enData2.length);
|
|
//
|
|
//
|
|
// return new DataAndMac(enData, mac.getData());
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public DataAndMacCheck SYD_SM4_CheckMacAndDecrypt_ShortData(int iEncKeyIndex, int iMacKeyIndex, byte[] pcData, byte[] macs) {
|
|
|
|
try {
|
|
if ( ! ConnectHandlerManager.isInited() ) {
|
|
throw new SydApiException(-1);
|
|
}
|
|
|
|
byte[] decryptedData = new byte[pcData.length];
|
|
IntByReference decryptedDataLen = new IntByReference(decryptedData.length);
|
|
|
|
|
|
int i = SydLibrary.INSTANCE.SYD_SM4_Decrypt_Mac_ShortData(
|
|
ConnectHandlerManager.getHandler(),
|
|
iEncKeyIndex,
|
|
iMacKeyIndex,
|
|
pcData,
|
|
pcData.length,
|
|
macs,
|
|
decryptedData,
|
|
decryptedDataLen
|
|
);
|
|
|
|
byte[] data = new byte[decryptedDataLen.getValue()];
|
|
System.arraycopy(decryptedData, 0, data, 0, data.length);
|
|
System.out.println("outlen=" + data.length);
|
|
|
|
if ( 0 == i ){
|
|
return new DataAndMacCheck(data, true);
|
|
} if (0x01000010 == i) {
|
|
return new DataAndMacCheck(data, false);
|
|
} else {
|
|
throw new SydApiException(i);
|
|
}
|
|
} catch (Exception e) {
|
|
if ( e instanceof SydApiException) {
|
|
throw e;
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
|
|
|
|
// FutureTask<DataAndMacCheck> task = builder.getLongLinkWorks().fTask(new Callable<DataAndMacCheck>() {
|
|
// @Override
|
|
// public DataAndMacCheck call() throws Exception {
|
|
// return builder.get().SYD_SM4_CheckMacAndDecrypt_ShortData(iEncKeyIndex, iMacKeyIndex, pcData, mac);
|
|
// }
|
|
// });
|
|
// try {
|
|
// return task.get();
|
|
// } catch (Exception e) {
|
|
// throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
// }
|
|
}
|
|
|
|
@Override
|
|
public List<DataAndMac> SYD_SM4_EncryptAndMac_BatchData(int[] iEncKeyIndex, int[] iMacKeyIndex, List<byte[]> pcData) {
|
|
if ( ! ConnectHandlerManager.isInited() ) {
|
|
throw new SydApiException(-1);
|
|
}
|
|
|
|
try {
|
|
int size = pcData.size();
|
|
|
|
// 准备输入参数 - 直接使用 byte[][]
|
|
byte[][] pcDataArray = pcData.toArray(new byte[0][]);
|
|
int[] iDataLen = pcData.stream()
|
|
.mapToInt(bytes -> bytes.length)
|
|
.toArray();
|
|
|
|
// 准备输出缓冲区
|
|
byte[][] pcEncData = new byte[size][];
|
|
int[] iEncDataLen = new int[size];
|
|
for (int i = 0; i < size; i++) {
|
|
int maxEncLen = ((pcData.get(i).length + 15) / 16 * 16);
|
|
pcEncData[i] = new byte[maxEncLen];
|
|
iEncDataLen[i] = maxEncLen;
|
|
}
|
|
|
|
byte[] pcMac = new byte[16];
|
|
|
|
// 调用加密函数
|
|
int result = SydLibrary.INSTANCE.SYD_SM4_Encrypt_Mac_BatchData(
|
|
ConnectHandlerManager.getHandler(),
|
|
iEncKeyIndex,
|
|
iMacKeyIndex,
|
|
pcDataArray,
|
|
iDataLen,
|
|
size,
|
|
pcEncData,
|
|
iEncDataLen,
|
|
pcMac);
|
|
|
|
if (0 == result) {
|
|
// 转换结果为Java风格的对象列表
|
|
List<DataAndMac> results = new ArrayList<>();
|
|
for (int i = 0; i < size; i++) {
|
|
results.add(new DataAndMac(pcEncData[i], pcMac));
|
|
}
|
|
|
|
return results;
|
|
} else {
|
|
throw new SydApiException(result);
|
|
}
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
|
|
// FutureTask<List<DataAndMac>> task = builder.getLongLinkWorks().fTask(new Callable<List<DataAndMac>>() {
|
|
// @Override
|
|
// public List<DataAndMac> call() throws Exception {
|
|
// return builder.get().SYD_SM4_EncryptAndMac_BatchData(iEncKeyIndex, iMacKeyIndex, pcData);
|
|
// }
|
|
// });
|
|
// try {
|
|
// return task.get();
|
|
// } catch (Exception e) {
|
|
// throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
// }
|
|
|
|
}
|
|
|
|
@Override
|
|
public List<DataAndMacCheck> SYD_SM4_CheckMacAndDecrypt_BatchData(int[] iEncKeyIndex, int[] iMacKeyIndex, List<DataAndMac> pcData) {
|
|
|
|
int size = pcData.size();
|
|
|
|
// 准备输入参数
|
|
byte[][] pcEncData = pcData.stream()
|
|
.map(DataAndMac::getData)
|
|
.toArray(byte[][]::new);
|
|
|
|
int[] iEncDataLen = pcData.stream()
|
|
.mapToInt(d -> d.getData().length)
|
|
.toArray();
|
|
|
|
byte[][] pcMac = pcData.stream()
|
|
.map(d -> d.getMac())
|
|
.toArray(byte[][]::new);
|
|
|
|
// 准备输出缓冲区
|
|
byte[][] pcOutData = new byte[size][];
|
|
int[] iOutDataLen = new int[size];
|
|
for (int i = 0; i < size; i++) {
|
|
int maxOutLen = pcData.get(i).getData().length;
|
|
pcOutData[i] = new byte[maxOutLen];
|
|
iOutDataLen[i] = maxOutLen;
|
|
}
|
|
|
|
int[] iCheckRet = new int[size];
|
|
|
|
// 调用解密函数
|
|
int result = SydLibrary.INSTANCE.SYD_SM4_Decrypt_Mac_BatchData(
|
|
ConnectHandlerManager.getHandler(),
|
|
iEncKeyIndex,
|
|
iMacKeyIndex,
|
|
pcEncData,
|
|
iEncDataLen,
|
|
pcMac,
|
|
size,
|
|
pcOutData,
|
|
iOutDataLen,
|
|
iCheckRet);
|
|
|
|
if (0 == result) {
|
|
// 转换结果为Java风格的对象列表
|
|
List<DataAndMacCheck> results = new ArrayList<>();
|
|
for (int i = 0; i < size; i++) {
|
|
results.add(new DataAndMacCheck(pcOutData[i], iCheckRet[i] == 0));
|
|
}
|
|
|
|
return results;
|
|
} else {
|
|
throw new SydApiException(result);
|
|
}
|
|
|
|
// FutureTask<List<DataAndMacCheck>> task = builder.getLongLinkWorks().fTask(new Callable<List<DataAndMacCheck>>() {
|
|
// @Override
|
|
// public List<DataAndMacCheck> call() throws Exception {
|
|
// return builder.get().SYD_SM4_CheckMacAndDecrypt_BatchData(iEncKeyIndex, iMacKeyIndex, pcData);
|
|
// }
|
|
// });
|
|
// try {
|
|
// return task.get();
|
|
// } catch (Exception e) {
|
|
// throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
// }
|
|
}
|
|
|
|
@Override
|
|
public ISM4 initSM4(int iKeyIndex, int ende) {
|
|
return new SydSM4(this, iKeyIndex, ende);
|
|
}
|
|
|
|
@Override
|
|
public ISM3 initSM3() {
|
|
return new SydSM3(this);
|
|
}
|
|
|
|
@Override
|
|
public ISM4Mac initSM4Mac(int iKeyIndex) {
|
|
return new SydSM4Mac(this, iKeyIndex);
|
|
}
|
|
|
|
|
|
@Override
|
|
public List<byte[]> SYD_SM4_BatchData(int[] iKeyIndex, List<byte[]> pcData, int iFlag) {
|
|
if ( null == iKeyIndex || null == pcData ) {
|
|
throw new IllegalArgumentException("批量输入数据为 null");
|
|
}
|
|
|
|
if ( iKeyIndex.length != pcData.size() ) {
|
|
throw new IllegalArgumentException("批量输入数据密钥和数据数量不等");
|
|
}
|
|
|
|
if ( 0 == iKeyIndex.length ) {
|
|
return new ArrayList<>();
|
|
}
|
|
// 将数据进行分组,防止超长。
|
|
List<List<byte[]>> dataGroups = new ArrayList<>();
|
|
List<List<Integer>> keyGroups = new ArrayList<>();
|
|
int totalLen = 0;
|
|
|
|
List<byte[]> curDataGroup = new ArrayList<>();
|
|
List<Integer> curKeyGroup = new ArrayList<>();
|
|
|
|
for (int i = 0; i < pcData.size(); i++) {
|
|
byte[] data = pcData.get(i);
|
|
if (null == data) {
|
|
data = new byte[0];
|
|
}
|
|
if (
|
|
curDataGroup.size() > 9 // 分组小于等于 9 个
|
|
|| (totalLen + data.length > BATCH_SIZE) // 总大小小于 BATCH_SIZE
|
|
) { // 扩展包
|
|
dataGroups.add(curDataGroup);
|
|
keyGroups.add(curKeyGroup);
|
|
|
|
curDataGroup = new ArrayList<>();
|
|
curKeyGroup = new ArrayList<>();
|
|
totalLen = 0;
|
|
}
|
|
|
|
|
|
curDataGroup.add(data);
|
|
curKeyGroup.add(iKeyIndex[i]);
|
|
|
|
totalLen += data.length;
|
|
|
|
}
|
|
|
|
dataGroups.add(curDataGroup);
|
|
keyGroups.add(curKeyGroup);
|
|
|
|
// 并发处理
|
|
List<FutureTask<List<byte[]>>> tasks = new ArrayList<>();
|
|
for (int i = 0; i < dataGroups.size(); i++) {
|
|
|
|
int finalI = i;
|
|
FutureTask<List<byte[]>> task = builder.getLongLinkWorks().fTask(new Callable<List<byte[]>>() {
|
|
@Override
|
|
public List<byte[]> call() throws Exception {
|
|
SydApi api = builder.get();
|
|
return api.SYD_SM4_BatchData(toIntArray(keyGroups.get(finalI)), dataGroups.get(finalI), iFlag);
|
|
}
|
|
});
|
|
tasks.add(task);
|
|
}
|
|
|
|
try {
|
|
List<byte[]> ret = new ArrayList<>();
|
|
for (FutureTask<List<byte[]>> t : tasks) {
|
|
ret.addAll(t.get());
|
|
}
|
|
return ret;
|
|
|
|
}
|
|
catch (ExecutionException e) {
|
|
Throwable cause = e.getCause();
|
|
if (cause instanceof SydApiException) {
|
|
throw (SydApiException) cause;
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101);
|
|
}
|
|
catch (Exception e) {
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public List<byte[]> SYD_SM4Mac_BatchData(int[] iKeyIndex, List<byte[]> pcData) {
|
|
if ( null == iKeyIndex || null == pcData ) {
|
|
throw new IllegalArgumentException("批量输入数据为 null");
|
|
}
|
|
|
|
if ( iKeyIndex.length != pcData.size() ) {
|
|
throw new IllegalArgumentException("批量输入数据密钥和数据数量不等");
|
|
}
|
|
|
|
if ( 0 == iKeyIndex.length ) {
|
|
return new ArrayList<>();
|
|
}
|
|
// 将数据进行分组,防止超长。
|
|
List<List<byte[]>> dataGroups = new ArrayList<>();
|
|
List<List<Integer>> keyGroups = new ArrayList<>();
|
|
int totalLen = 0;
|
|
|
|
List<byte[]> curDataGroup = new ArrayList<>();
|
|
List<Integer> curKeyGroup = new ArrayList<>();
|
|
|
|
for (int i = 0; i < pcData.size(); i++) {
|
|
byte[] data = pcData.get(i);
|
|
if (null == data) {
|
|
data = new byte[0];
|
|
}
|
|
if (
|
|
curDataGroup.size() > 9 // 分组小于等于 9 个
|
|
|| (totalLen + data.length > BATCH_SIZE) // 总大小小于 BATCH_SIZE
|
|
) {// 扩展包
|
|
dataGroups.add(curDataGroup);
|
|
keyGroups.add(curKeyGroup);
|
|
|
|
curDataGroup = new ArrayList<>();
|
|
curKeyGroup = new ArrayList<>();
|
|
totalLen = 0;
|
|
}
|
|
|
|
curDataGroup.add(data);
|
|
curKeyGroup.add(iKeyIndex[i]);
|
|
|
|
totalLen += data.length;
|
|
}
|
|
|
|
dataGroups.add(curDataGroup);
|
|
keyGroups.add(curKeyGroup);
|
|
|
|
// 并发处理
|
|
List<FutureTask<List<byte[]>>> tasks = new ArrayList<>();
|
|
for (int i = 0; i < dataGroups.size(); i++) {
|
|
|
|
int finalI = i;
|
|
FutureTask<List<byte[]>> task = builder.getLongLinkWorks().fTask(new Callable<List<byte[]>>() {
|
|
@Override
|
|
public List<byte[]> call() throws Exception {
|
|
SydApi api = builder.get();
|
|
return api.SYD_SM4Mac_BatchData(toIntArray(keyGroups.get(finalI)), dataGroups.get(finalI));
|
|
}
|
|
});
|
|
tasks.add(task);
|
|
}
|
|
|
|
try {
|
|
List<byte[]> ret = new ArrayList<>();
|
|
for (FutureTask<List<byte[]>> t : tasks) {
|
|
List<byte[]> macs = t.get();
|
|
ret.addAll(macs);
|
|
}
|
|
return ret;
|
|
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean[] SYD_SM4Mac_BatchData(int[] iKeyIndex, List<byte[]> pcData, List<byte[]> pcMac) {
|
|
if ( null == iKeyIndex || null == pcData ) {
|
|
throw new IllegalArgumentException("批量输入数据为 null");
|
|
}
|
|
|
|
if ( iKeyIndex.length != pcData.size() ) {
|
|
throw new IllegalArgumentException("批量输入数据密钥和数据数量不等");
|
|
}
|
|
|
|
if ( 0 == iKeyIndex.length ) {
|
|
return new boolean[0];
|
|
}
|
|
|
|
// 将数据进行分组,防止超长。
|
|
List<List<byte[]>> dataGroups = new ArrayList<>();
|
|
List<List<Integer>> keyGroups = new ArrayList<>();
|
|
List<List<byte[]>> macGroups = new ArrayList<>();
|
|
int totalLen = 0;
|
|
|
|
List<byte[]> curDataGroup = new ArrayList<>();
|
|
List<Integer> curKeyGroup = new ArrayList<>();
|
|
List<byte[]> curMacGroup = new ArrayList<>();
|
|
|
|
for (int i = 0; i < pcData.size(); i++) {
|
|
byte[] data = pcData.get(i);
|
|
if (null == data) {
|
|
data = new byte[0];
|
|
}
|
|
if (
|
|
curDataGroup.size() > 9 // 分组小于等于 9 个
|
|
|| (totalLen + data.length > BATCH_SIZE) // 总大小小于 BATCH_SIZE
|
|
) {
|
|
// 扩展包
|
|
dataGroups.add(curDataGroup);
|
|
keyGroups.add(curKeyGroup);
|
|
macGroups.add(curMacGroup);
|
|
|
|
curDataGroup = new ArrayList<>();
|
|
curKeyGroup = new ArrayList<>();
|
|
curMacGroup = new ArrayList<>();
|
|
totalLen = 0;
|
|
}
|
|
|
|
|
|
curDataGroup.add(data);
|
|
curKeyGroup.add(iKeyIndex[i]);
|
|
curMacGroup.add(pcMac.get(i));
|
|
totalLen += data.length;
|
|
}
|
|
|
|
dataGroups.add(curDataGroup);
|
|
keyGroups.add(curKeyGroup);
|
|
macGroups.add(curMacGroup);
|
|
|
|
// 并发处理
|
|
List<FutureTask<boolean[]>> tasks = new ArrayList<>();
|
|
for (int i = 0; i < dataGroups.size(); i++) {
|
|
|
|
int finalI = i;
|
|
FutureTask<boolean[]> task = builder.getLongLinkWorks().fTask(new Callable<boolean[]>() {
|
|
@Override
|
|
public boolean[] call() throws Exception {
|
|
SydApi api = builder.get();
|
|
return api.SYD_SM4Mac_BatchData(
|
|
toIntArray(keyGroups.get(finalI)),
|
|
dataGroups.get(finalI),
|
|
macGroups.get(finalI)
|
|
);
|
|
}
|
|
});
|
|
tasks.add(task);
|
|
}
|
|
|
|
try {
|
|
List<Boolean> ret = new ArrayList<>();
|
|
for (FutureTask<boolean[]> t : tasks) {
|
|
boolean[] rets = t.get();
|
|
for (boolean r : rets) {
|
|
ret.add(r);
|
|
}
|
|
}
|
|
return toBoolArray(ret);
|
|
|
|
} catch (Exception e) {
|
|
if ( e.getCause() instanceof SydApiException) {
|
|
throw (SydApiException) e.getCause();
|
|
}
|
|
throw new SydApiException("并行任务执行失败", 0xC101, e);
|
|
}
|
|
}
|
|
} |