package com.rj.util; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Map; import java.util.TreeMap; import java.util.stream.Collectors; /** hxrd 前端 {@code getSignHeader} 对应的 SHA256 签名。 */ public final class HxrGoodsSignUtil { private HxrGoodsSignUtil() {} /** * 按前端规则生成签名:参数键排序 → {@code k=v&...} → 拼接 appStr → SHA256 hex。 * * @param params 请求参数 + {@code timestamp} + {@code noncestr} * @param appStr 前端 configs.appStr */ public static String computeSign(Map params, String appStr) { TreeMap sorted = new TreeMap<>(); if (params != null) { for (Map.Entry entry : params.entrySet()) { Object value = entry.getValue(); if (value == null) { continue; } String text = String.valueOf(value); if (text.isEmpty()) { continue; } sorted.put(entry.getKey(), value); } } String payload = sorted.entrySet().stream() .map(e -> e.getKey() + "=" + e.getValue()) .collect(Collectors.joining("&")); if (appStr != null && !appStr.isEmpty()) { payload += appStr; } return sha256Hex(payload); } private static String sha256Hex(String input) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8)); StringBuilder sb = new StringBuilder(hash.length * 2); for (byte b : hash) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("SHA-256 not available", e); } } }