【问题标题】:Base10 encryption for a String字符串的 Base10 加密
【发布时间】:2020-06-03 06:43:32
【问题描述】:

我正在尝试找到一种方法来获取字符串的 base10 值。使用所示的哈希码函数很容易实现这一点。但是我注意到这些值是连续的或接近的。下面的例子。

我在这里没有处理安全密码或任何东西,只是希望能够将字符串转换为 base10 值,并且在我这样做时总是得到相同的值。

可能有点过头了,但查看了现有的哈希选项,例如 MessageDigest。但是它们都是 Base64(或多或少),但对于 Base10 来说没有一个,考虑到它一开始就不安全,这是可以预期的。

我正在考虑的一个可能选项是使用 MessageDigest,获取一个 base64 值并对其进行正则表达式以仅提取所有数字。这意味着每次我通过消息摘要和正则表达式进行编码以仅获取 Base10 值时,我应该始终获得相同的值。

我的问题是,有没有更好的方法来做到这一点?而不是在我的情况下真正需要的加密使其复杂化。

我只想将示例转换如下:

String s1 = "Sample00000000001";
// after encoding, getting Base10 value like -> 8725342728354

String s2 = "Sample00000000002"; 
// after encoding, getting Base10 value like -> 11576232138652 (random, not sequential even though only 1 character changed). 

尝试使用 Java Util 中的 Base64 按顺序(或关闭)产生结果,因此不是我想要的。仍然需要从这里正则表达式出 Base10 值。

public static void main(String[] args) {
    String salt = "Sample";
    String num = "00000000001";
    Base64.Encoder encoder = Base64.getEncoder();
    Base64.Decoder decoder = Base64.getDecoder();
    String value  = salt + num;
    String encoded = encoder.encodeToString(value.getBytes());
    String decoded = new String(decoder.decode(encoded));
    // 00000000001 gives U2FtcGxlMDAwMDAwMDAwMDE=
    // 00000000002 gives U2FtcGxlMDAwMDAwMDAwMDI=
}

使用再次以顺序或关闭结束的哈希码

public static void main(String[] args) {

    String salt = "Sample";
    String num = "00000000002";

    String v = salt+num;
    int hash = v.hashCode();
    System.out.println(hash);
}

我正在查看的最后一个选项,使用像 Bouncy castle 或内置 MessageDigest 这样的库。

假设编码已完成,并且我已将其分配给下面的变量“值”。我只能通过正则表达式从中提取 Base10 值,如下所示。

String value = "HASDJHSDGF3423HIHGH234565BJB666";
long result =  Long.valueOf(value.replaceAll("\\D+",""));
System.out.println(result); // end up with 3423234565666 as expected. 

我目前倾向于使用 MessageDigest 的最后一个选项,但正在寻找更好的方法来执行此操作的建议/选项。感谢任何帮助。谢谢。

【问题讨论】:

  • 目前还不清楚您的目标是什么。这应该是可逆的吗?为什么顺序值不好?这个号码的用途是什么?
  • Base 64 相似性是有意义的,因为它只是一种以最少字符数表示字节的方式,因此字符串的微小变化只会改变少量字节。为了实现您正在寻找的那种随机性,建议使用一种非常简单的加密算法 - 它们通常会输出一个字节数组,因此您只需将每个字节的基数 10 整数值相加即可。
  • 或者像你说的那样,摘要会更容易,如果不考虑安全性,那么只需 MD5 就可以了。
  • @LouisWasserman 我不打算反转它,但无论我采用哪种散列方法,我总是希望为特定的 String 值获得相同的散列值。就目的而言,我们将散列值用于一些内部决策机制。它不能是连续的。
  • 顺序排列到底有什么问题?如果它在反转位中是连续的 - 例如Integer.reverse(string.hashCode())——够了吗?

标签: java spring-boot


【解决方案1】:

您可以使用消息摘要生成一个字节数组,然后将它们读取为整数:

   public static void main(String[] args) {

        String salt = "Sample";
        String num = "00000000002";
        String num2 = "00000000001";

        hash(salt, num);
        hash(salt, num2);
    }

    private static void hash(String salt, String num) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.reset();
            ByteBuffer bytes = ByteBuffer.wrap(digest.digest((num + digest).getBytes()));
            System.out.println(bytes.asIntBuffer().get());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

或者您可以使用 Random 类(相同的种子产生相同的“随机”值)(从性能的角度来看,我不确定其含义)

   private static void hash(String salt, String num) {
        System.out.println(new Random(num.hashCode() + salt.hashCode()).nextInt());
    }

【讨论】:

    【解决方案2】:

    方法hashCode的目的是在HashMap等数据结构中搜索对象。标准实现基于内存中的地址,而不是字符串的内容,因此对于您的情况,它是无用的。

    Base64 不是加密,也不是散列函数。它只转换二进制数据,因此可以将其存储为文本,因此输入的微小变化会导致输出的微小变化。

    您需要的是使用一些真正的哈希函数,如 SHA 并将结果转换为您的格式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-01
      • 2018-08-26
      • 1970-01-01
      相关资源
      最近更新 更多