From 154bb6bf7f098a6076dd1bab9f5b304cc17bbed6 Mon Sep 17 00:00:00 2001 From: zf <1603559716@qq.com> Date: 星期一, 11 九月 2023 15:32:16 +0800 Subject: [PATCH] 签名 --- ruoyi-common/src/main/java/com/ruoyi/common/signature/TokenUtils.java | 78 +++++++ ruoyi-common/src/main/java/com/ruoyi/common/signature/SignatureUtils.java | 127 ++++++++++++ ruoyi-common/src/main/java/com/ruoyi/common/signature/SkipHttpsUtils.java | 46 ++++ ruoyi-common/src/main/java/com/ruoyi/common/signature/Signature.java | 166 ++++++++++++++++ pom.xml | 11 + ruoyi-common/src/main/java/com/ruoyi/common/signature/Signature11.java | 121 ++++++++++++ ruoyi-common/pom.xml | 9 7 files changed, 557 insertions(+), 1 deletions(-) diff --git a/pom.xml b/pom.xml index ce5a9ec..04639c3 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,16 @@ <artifactId>hutool-all</artifactId> <version>${hutool.version}</version> </dependency> - + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.14</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.5</version> + </dependency> </dependencies> </dependencyManagement> diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 54060bb..3726c1a 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -139,6 +139,15 @@ <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> </dependencies> </project> \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/signature/Signature.java b/ruoyi-common/src/main/java/com/ruoyi/common/signature/Signature.java new file mode 100644 index 0000000..6a3d6c8 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/signature/Signature.java @@ -0,0 +1,166 @@ +package com.ruoyi.common.signature; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLEncoder; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.gson.Gson; + +/** + * @email 1603559716@qq.com + * @author: zf + * @date: 2023/9/7 + * @time: 11:06 + */ +public class Signature { + private static final Logger logger = LoggerFactory.getLogger(Signature.class); + // 接口服务地址 + static String restSever = "https://inspurtestcx.saws.org.cn/sjjh/api/v1/exam/plan/enroll/download"; + // 应用标识 + static String appKey = "hj92qe"; + // 加密算法 + static String signMethod = "SHA-256"; + // 身份系统签发给应用对接的密钥 + static String appPwd = "dxep6j"; + + public static void main(String[] args) { + // 时间戳 + Long ts = Calendar.getInstance().getTime().getTime(); + // 随机数 + String once = RandomStringUtils.randomAlphanumeric(32); + // 接口header 中的公共参数 + String commonParamUrl = String.format("appKey=%s" + "&" + "ts=%s" + "&" + "once=%s" + "&" + "signMethod=%s", appKey, ts, once, signMethod); + // 创建HttpClient 对象 + CloseableHttpClient httpclient = (CloseableHttpClient) SkipHttpsUtils.wrapClient(); + /** + * GET 查询接口演示代码 + */ + String startTime = "2023-05-25 00:00:00"; + String endTime = "2023-06-01 21:00:00"; + try { + startTime = URLEncoder.encode(startTime, "UTF-8"); + endTime = URLEncoder.encode(endTime, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e.getCause()); + } + String getQueryParam = "startTime=" + startTime + "&endTime=" + endTime; + System.out.println(getQueryParam); + String getFullUrl = restSever + "?" + getQueryParam; + HttpGet httpGet = new HttpGet(getFullUrl); + // get 请求查询参数, 用在 URL 上的, 这里若是通过 ID 查询的, 接口中 ID 是作为路径存在的, 所以需要将 ID 组合成 + String getAllParamUrl = commonParamUrl + "&" + getQueryParam; + // 对参数签名, 并放入请求 header 中的 signData 参数中 + try { + // 签名数据 + String signData = TokenUtils.getSignature(appPwd, getAllParamUrl); + // 添加 header 参数 appCode、timestamp、signatureNonce、signature + httpGet.addHeader("appKey", appKey); + httpGet.addHeader("ts", ts.toString()); + httpGet.addHeader("once", once); + httpGet.addHeader("signMethod", signMethod); + System.out.println("once:" + once); + httpGet.addHeader("signData", signData); + System.out.println("headers:" + httpGet.getAllHeaders()); + String urlStr = httpGet.getURI().toString(); + // 公共参数 URL + System.out.println("commonParamter:" + urlStr); + if (StringUtils.endsWith(urlStr, "/")) { + urlStr = StringUtils.removeEnd(urlStr, "/"); + } + httpGet.setURI(new URI(urlStr)); + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(3000).setSocketTimeout(3000).build(); + httpGet.setConfig(requestConfig); + System.out.println("urlStr in request:" + httpGet.getURI().toString()); + // 执行请求 + CloseableHttpResponse response = httpclient.execute(httpGet); + // 取响应的结果 + int statusCode = response.getStatusLine().getStatusCode(); + // 打印响应结果 + if (statusCode == HttpStatus.SC_OK) { + String resp = EntityUtils.toString(response.getEntity(), "utf-8"); + System.out.println("status:" + statusCode); + System.out.println("result:" + resp); + } + } catch (URISyntaxException e) { + logger.error("签名失败: ", e); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + /** + * PUT 修改接口的演示代码,POST 与 PUT 类似 + */ + String ID = "aa03a5c692cf480b87887e0ff8cfe566"; + // 这里若是通过 ID 查询的, 接口中 ID 是作为路径存在的, 所以需要将 ID 组合成 + String putQueryParam = "ID=" + ID; + + String putFullUrl = restSever + "/" + ID; + // 访问用户接口 + HttpPut httpPut = new HttpPut(putFullUrl); + // 模拟 POST/PUT 的 body 中数据, 需转为 JSON 进行签名。GET 则没有这部分内容。 + Map<String, Object> dataMap = new HashMap<String, Object>(); + dataMap.put("USER_NAME", "张三"); + String bodyParam = new Gson().toJson(dataMap); + String postAllParamUrl = commonParamUrl + "&" + putQueryParam + "&bodyData=" + bodyParam; + StringEntity bodyData = new StringEntity(bodyParam.toString(), "UTF-8"); + httpPut.setEntity(bodyData); + // 对参数签名, 并放入请求 header 中的 signData 参数中 + try { + // 签名数据 + String signData = TokenUtils.getSignature(appPwd, postAllParamUrl); + // 添加 header 参数 appCode、timestamp、signatureNonce、signature + httpPut.addHeader("appKey", appKey); + httpPut.addHeader("ts", ts.toString()); + httpPut.addHeader("once", once); + System.out.println("once:" + once); + httpPut.addHeader("signData", signData); + System.out.println("headers:" + httpPut.getAllHeaders()); + String urlStr = httpPut.getURI().toString(); + // 公共参数 URL + System.out.println("commonParamter:" + urlStr); + if (StringUtils.endsWith(urlStr, "/")) { + urlStr = StringUtils.removeEnd(urlStr, "/"); + } + httpPut.setURI(new URI(urlStr)); + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(3000).setSocketTimeout(3000).build(); + httpPut.setConfig(requestConfig); + System.out.println("urlStr in request:" + httpPut.getURI().toString()); + // 执行请求 + CloseableHttpResponse response = httpclient.execute(httpPut); + // 取响应的结果 + int statusCode = response.getStatusLine().getStatusCode(); + // 打印响应结果 + if (statusCode == HttpStatus.SC_OK) { + String resp = EntityUtils.toString(response.getEntity(), "utf-8"); + System.out.println("status:" + statusCode); + System.out.println("result:" + resp); + } + } catch (URISyntaxException e) { + logger.error("签名失败: ", e); + + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/signature/Signature11.java b/ruoyi-common/src/main/java/com/ruoyi/common/signature/Signature11.java new file mode 100644 index 0000000..bd6f9de --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/signature/Signature11.java @@ -0,0 +1,121 @@ +package com.ruoyi.common.signature; + +import com.alibaba.fastjson2.JSON; +import com.google.gson.Gson; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLEncoder; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; + +/** + * @email 1603559716@qq.com + * @author: zf + * @date: 2023/9/7 + * @time: 11:06 + */ +public class Signature11 { + private static final Logger logger = LoggerFactory.getLogger(Signature11.class); + // 接口服务地址 考生信息下载 + static String restSever = "https://inspurtestcx.saws.org.cn/sjjh/api/v1/exam/plan/enroll/download"; + // 应用标识 + static String appKey = "hj92qe"; + // 加密算法 + static String signMethod = "SHA-256"; + // 身份系统签发给应用对接的密钥 + static String appPwd = "dxep6j"; + + public static void main(String[] args) { + // 时间戳 + Long ts = Calendar.getInstance().getTime().getTime(); + // 随机数 + String once = RandomStringUtils.randomAlphanumeric(32); + // 接口 header 中的公共参数 + String commonParamUrl = String.format("appKey=%s" + "&" + "ts=%s" + "&" + "once=%s" + "&" + + "signMethod=%s", appKey, ts, once, signMethod); + // 创建 HttpClient 对象 + CloseableHttpClient httpclient = (CloseableHttpClient) SkipHttpsUtils.wrapClient(); + /** + * GET 查询接口演示代码 + */ + String startTime = "2018-05-25 00:00:00"; + String endTime = "2023-06-01 21:00:00"; + try { + startTime = URLEncoder.encode(startTime, "UTF-8"); + endTime = URLEncoder.encode(endTime, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e.getCause()); + } + String getQueryParam = "startTime=" + startTime + "&endTime=" + endTime; + System.out.println(getQueryParam); + + String getFullUrl = restSever + "?" + getQueryParam; + HttpGet httpGet = new HttpGet(getFullUrl); + // get 请求查询参数, 用在 URL 上的, 这里若是通过 ID 查询的, 接口中 ID 是作为路径存在的, 所以需要将 ID 组成 + String getAllParamUrl = commonParamUrl + "&" + getQueryParam; + + // 对参数签名, 并放入请求 header 中的 signData 参数中 + try { + // 签名数据 + String signData = TokenUtils.getSignature(appPwd, getAllParamUrl); + // 添加 header 参数 appCode、 timestamp、 signatureNonce、 signature + httpGet.addHeader("appKey", appKey); + httpGet.addHeader("ts", ts.toString()); + httpGet.addHeader("once", once); + httpGet.addHeader("signMethod", signMethod); + System.out.println("once:" + once); + httpGet.addHeader("signData", signData); + System.out.println("headers:" + httpGet.getAllHeaders()); + String urlStr = httpGet.getURI().toString(); + // 公共参数 URL + System.out.println("commonParamter:" + urlStr); + if (StringUtils.endsWith(urlStr, "/")) { + urlStr = StringUtils.removeEnd(urlStr, "/"); + } + httpGet.setURI(new URI(urlStr)); + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(6000) + .setConnectionRequestTimeout(6000).setSocketTimeout(6000).build(); + httpGet.setConfig(requestConfig); + System.out.println("urlStr in request:" + httpGet.getURI().toString()); + // 执行请求 + CloseableHttpResponse response = httpclient.execute(httpGet); + // 取响应的结果 + int statusCode = response.getStatusLine().getStatusCode(); + // 打印响应结果 + if (statusCode == HttpStatus.SC_OK) { + String resp = EntityUtils.toString(response.getEntity(), "utf-8"); + System.out.println("status:" + statusCode); + Object object = JSON.parse(resp); + System.out.println("result:" + resp); + } else { + System.out.println(statusCode); + } + } catch (URISyntaxException e) { + logger.error("签名失败: ", e); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } +} + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/signature/SignatureUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/signature/SignatureUtils.java new file mode 100644 index 0000000..9a17e45 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/signature/SignatureUtils.java @@ -0,0 +1,127 @@ +package com.ruoyi.common.signature; + +import com.alibaba.fastjson2.JSON; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLEncoder; +import java.util.Calendar; + +/** + * @email 1603559716@qq.com + * @author: zf + * @date: 2023/9/8 + * @time: 14:52 + */ +public class SignatureUtils { + private static final Logger logger = LoggerFactory.getLogger(SignatureUtils.class); + // 接口服务地址 + private static final String restSever = "https://inspurtestcx.saws.org.cn/sjjh"; + // 应用标识 + private static final String appKey = "hj92qe"; + // 加密算法 + private static final String signMethod = "SHA-256"; + // 身份系统签发给应用对接的密钥 + private static final String appPwd = "dxep6j"; + + /** + * 获取数据接口 + * @param getQueryParam + * @return + */ + public static Object getObject(String getQueryParam,String url){ + // 时间戳 + Long ts = Calendar.getInstance().getTime().getTime(); + // 随机数 + String once = RandomStringUtils.randomAlphanumeric(32); + // 接口header 中的公共参数 + String commonParamUrl = String.format("appKey=%s" + "&" + "ts=%s" + "&" + "once=%s" + "&" + "signMethod=%s", appKey, ts, once, signMethod); + + String getFullUrl = restSever + url + "?" + getQueryParam; + HttpGet httpGet = new HttpGet(getFullUrl); + // get 请求查询参数, 用在 URL 上的, 这里若是通过 ID 查询的, 接口中 ID 是作为路径存在的, 所以需要将 ID 组成 + String getAllParamUrl = commonParamUrl + "&" + getQueryParam; + // 创建 HttpClient 对象 + CloseableHttpClient httpclient = (CloseableHttpClient) SkipHttpsUtils.wrapClient(); + // 对参数签名, 并放入请求 header 中的 signData 参数中 + try { + + // 签名数据 + String signData = TokenUtils.getSignature(appPwd, getAllParamUrl); + // 添加 header 参数 appCode、 timestamp、 signatureNonce、 signature + httpGet.addHeader("appKey", appKey); + httpGet.addHeader("ts", ts.toString()); + httpGet.addHeader("once", once); + httpGet.addHeader("signMethod", signMethod); + System.out.println("once:" + once); + httpGet.addHeader("signData", signData); + System.out.println("headers:" + httpGet.getAllHeaders()); + String urlStr = httpGet.getURI().toString(); + // 公共参数 URL + System.out.println("commonParamter:" + urlStr); + if (StringUtils.endsWith(urlStr, "/")) { + urlStr = StringUtils.removeEnd(urlStr, "/"); + } + httpGet.setURI(new URI(urlStr)); + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(6000) + .setConnectionRequestTimeout(6000).setSocketTimeout(6000).build(); + httpGet.setConfig(requestConfig); + System.out.println("urlStr in request:" + httpGet.getURI().toString()); + // 执行请求 + CloseableHttpResponse response = httpclient.execute(httpGet); + // 取响应的结果 + int statusCode = response.getStatusLine().getStatusCode(); + // 打印响应结果 + if (statusCode == HttpStatus.SC_OK) { + String resp = EntityUtils.toString(response.getEntity(), "utf-8"); + System.out.println("status:" + statusCode); + Object object = JSON.parse(resp); + System.out.println("result:" + resp); + return object; + + } else { + System.out.println(statusCode); + } + } catch (URISyntaxException e) { + logger.error("签名失败: ", e); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static void main(String[] args) { + /** + * GET 查询接口演示代码 + */ + String startTime = "2018-05-25 00:00:00"; + String endTime = "2023-06-01 21:00:00"; + try { + startTime = URLEncoder.encode(startTime, "UTF-8"); + endTime = URLEncoder.encode(endTime, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e.getCause()); + } + String getQueryParam = "startTime=" + startTime + "&endTime=" + endTime; + System.out.println(getQueryParam); + Object obj = getObject(getQueryParam,"/api/v1/exam/plan/enroll/download"); + System.out.println(obj); + + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/signature/SkipHttpsUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/signature/SkipHttpsUtils.java new file mode 100644 index 0000000..3fe57c2 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/signature/SkipHttpsUtils.java @@ -0,0 +1,46 @@ +package com.ruoyi.common.signature; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +public class SkipHttpsUtils { + //绕过证书 + public static HttpClient wrapClient() { + try { + SSLContext ctx = SSLContext.getInstance("TLS"); + X509TrustManager tm = new X509TrustManager() { + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted(X509Certificate[] arg0, + String arg1) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] arg0, + String arg1) throws CertificateException { + } + }; + ctx.init(null, new TrustManager[] { tm }, null); + SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory( + ctx, NoopHostnameVerifier.INSTANCE); + CloseableHttpClient httpclient = HttpClients.custom() + .setSSLSocketFactory(ssf).build(); + return httpclient; + } catch (Exception e) { + return HttpClients.createDefault(); + } + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/signature/TokenUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/signature/TokenUtils.java new file mode 100644 index 0000000..e53e6af --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/signature/TokenUtils.java @@ -0,0 +1,78 @@ +package com.ruoyi.common.signature; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +/** + * @email 1603559716@qq.com + * @author: zf + * @date: 2023/9/7 + * @time: 11:01 + */ +public class TokenUtils { + private static final Logger logger = LoggerFactory.getLogger(TokenUtils.class); + private static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", + "b", "c", "d", "e", + "f" }; + public static String getSignature(String appPwd, String paramUrl) { + if (StringUtils.isNotBlank(paramUrl)) { + try { + paramUrl = URLDecoder.decode(paramUrl, "UTF-8"); + } catch (UnsupportedEncodingException e) { + logger.error("生成 signData 失败:", e); + throw new RuntimeException("生成 signData 失败:", e); + } + } + String[] paraArray = new String[] {}; + if (StringUtils.isNotBlank(paramUrl)) { + String[] queryArray = paramUrl.split("&"); + paraArray = (String[]) ArrayUtils.addAll(queryArray, paraArray); + } + Arrays.sort(paraArray); + StringBuffer buffer = new StringBuffer(); + buffer.append(appPwd); + buffer.append(":"); + for (int i = 0; i < paraArray.length; i++) { + buffer.append(paraArray[i]); + buffer.append("&"); + } + buffer.deleteCharAt(buffer.length() - 1); + buffer.append(":"); + buffer.append(appPwd); + MessageDigest md = null; + try { + md = MessageDigest.getInstance("SHA-256"); + md.update(buffer.toString().getBytes("UTF-8")); + } catch (NoSuchAlgorithmException e) { + logger.error("生成 signData 失败:", e); + throw new RuntimeException("生成 signData 失败.", e); + } catch (UnsupportedEncodingException e) { + logger.error("生成 signData 失败:", e); + throw new RuntimeException("生成 signData 失败.", e); + } + String encode = byteArrayToHexString(md.digest()); + return encode; + } + private static String byteArrayToHexString(byte[] byteArray) { + StringBuffer sb = new StringBuffer(); + for (byte byt : byteArray) { + sb.append(byteToHexString(byt)); + } + return sb.toString(); + } + private static String byteToHexString(byte byt) { + int n = byt; + if (n < 0) + n = 256 + n; + return hexDigits[n / 16] + hexDigits[n % 16]; + } +} + -- Gitblit v1.9.2