【问题标题】:How to hash a string in Android?如何在Android中对字符串进行哈希处理?
【发布时间】:2011-04-25 11:04:56
【问题描述】:

我正在开发一个 Android 应用程序,并且有几个字符串我想在发送到数据库之前对其进行加密。我想要一些安全、易于实现的东西,每次传递相同的数据时都会生成相同的东西,并且无论传递给它的字符串有多大,最好都会产生一个保持恒定长度的字符串。也许我正在寻找哈希。

【问题讨论】:

  • 哈希是单向的,如果您希望能够解密无法以恒定长度存储的数据,恕我直言
  • 我知道。这是为了验证,我只需要能够将一个值与另一个值进行比较,不需要“撤消”它。我知道我没有说我是否打算解密,所以感谢您的回复。
  • 无意冒犯,但您的问题标题具有误导性

标签: java android hash cryptography


【解决方案1】:

这个 sn-p 计算任何给定字符串的 md5

public String md5(String s) {
    try {
        // Create MD5 Hash
        MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
        digest.update(s.getBytes());
        byte messageDigest[] = digest.digest();

        // Create Hex String
        StringBuffer hexString = new StringBuffer();
        for (int i=0; i<messageDigest.length; i++)
            hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
        return hexString.toString();

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return "";
}

来源:http://www.androidsnippets.com/snippets/52/index.html

希望对你有用

【讨论】:

  • MD5,afaik,不被认为是可逆的。通常你会用它来散列一些东西,通常是密码或类似的东西,然后为了验证密码,你将运行相同的加密并将结果与​​存储的内容进行比较。
  • 此代码无法正常工作。生成的字符串中缺少一些“0”字符。我不知道为什么,但就是这样。
  • 这段代码失败时有一个特殊情况。当两位十六进制数中的第一个为零时。这段代码更好:stackoverflow.com/a/6565597/221135
  • 这将导致我尝试过的问题差异仅为 0--> 当我使用此函数进行转换时,它会给我结果(字符串为:a)结果:cc175b9c0f1b6a831c399e269772661 0cc175b9c0f1b6a831c399e269772661
  • 同意@SertalpBilal,正确答案在这里stackoverflow.com/a/4846511/1092591
【解决方案2】:
private static char[] hextable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

public static String byteArrayToHex(byte[] array) {
    String s = "";
    for (int i = 0; i < array.length; ++i) {
        int di = (array[i] + 256) & 0xFF; // Make it unsigned
        s = s + hextable[(di >> 4) & 0xF] + hextable[di & 0xF];
    }
    return s;
}

public static String digest(String s, String algorithm) {
    MessageDigest m = null;
    try {
        m = MessageDigest.getInstance(algorithm);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return s;
    }

    m.update(s.getBytes(), 0, s.length());
    return byteArrayToHex(m.digest());
}

public static String md5(String s) {
    return digest(s, "MD5");
}

【讨论】:

  • 是的 100%% 的工作我在 fucntion 上尝试过所有导致问题为 0 disacrding 但是这 3 个函数的解决方案给了我精确的解决方案,我已经将它与 .net md5 encription 匹配
  • 这是支持 UTF-8 的解决方案:stackoverflow.com/a/19589939/537694
【解决方案3】:

上面来自 (http://www.androidsnippets.org/snippets/52/index.html) 的函数有缺陷。如果 messageDigest 中的一个数字不是两个字符的十六进制值(即 0x09),它就不能正常工作,因为它没有用 0 填充。如果你四处搜索,你会发现那个函数和关于它的抱怨不工作。这里有一个更好的found in the comment section of this page,我稍微修改了一下:

public static String md5(String s) 
{
    MessageDigest digest;
    try
    {
        digest = MessageDigest.getInstance("MD5");
        digest.update(s.getBytes(Charset.forName("US-ASCII")),0,s.length());
        byte[] magnitude = digest.digest();
        BigInteger bi = new BigInteger(1, magnitude);
        String hash = String.format("%0" + (magnitude.length << 1) + "x", bi);
        return hash;
    }
    catch (NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    return "";
}

【讨论】:

  • 这个也有问题。尝试编码 q4m'x68n6_YDB4ty8VC4&}wqBtn^68W ,它给出 c70bb931f03b75af1591f261eb77d0b 而正确的应该是 0c70bb931f03b75af1591f261eb77d0b 前 0 个消散。
  • 不,亲爱的,它会导致问题,它会丢弃我在 .net 和 java 中尝试过的 0 这个函数丢弃 0
  • 我已经对其进行了编辑以处理前导零被丢弃...现在它可以正常工作了:)
【解决方案4】:

上面的答案几乎 100% 正确。使用 unicode 会失败。

    MessageDigest digest;
    try {
        digest = MessageDigest.getInstance("MD5");
        byte utf8_bytes[] = tag_xml.getBytes();
        digest.update(utf8_bytes,0,utf8_bytes.length);
        hash = new BigInteger(1, digest.digest()).toString(16);
    } 
    catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

需要字节数组的长度而不是字符串。

【讨论】:

  • 这里的 tag_xml 是什么?使用上面的代码尝试 q4m'x68n6_YDB4ty8VC4&}wqBtn^68W,结果是 c70bb931f03b75af1591f261eb77d0b 而不是 @Sertap Bilal 在评论中提到的 0c70bb931f03b75af1591f261eb77d0b这个答案上面的答案。
【解决方案5】:

Donut 在单个函数中的解决方案:

private static char[] hextable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

private static String md5(String s)
{
    MessageDigest digest;
    try
    {
        digest = MessageDigest.getInstance("MD5");
        digest.update(s.getBytes(), 0, s.length());
        byte[] bytes = digest.digest();

        String hash = "";
        for (int i = 0; i < bytes.length; ++i)
        {
            int di = (bytes[i] + 256) & 0xFF;
            hash = hash + hextable[(di >> 4) & 0xF] + hextable[di & 0xF];
        }

        return hash;
    }
    catch (NoSuchAlgorithmException e)
    {
    }

    return "";
}

【讨论】:

    【解决方案6】:
    MessageDigest md = MessageDigest.getInstance("MD5"); 
    md.update('yourstring');
    byte[] digest = md.digest();
    StringBuffer sb = new StringBuffer();
    for (byte b : digest) {
        sb.append(String.format("%02x", (0xFF & b)));
    }
    

    作者来晚了,但在此之前,我得到了 Integer.toHexString(0xff&amp;b) ,它从十六进制字符串中去除了前导 0。这让我挣扎了很久。希望对一些人有用。

    【讨论】:

      【解决方案7】:

      不工作方法:

      public static String md5(String s) {
          try {
              // Create MD5 Hash
              MessageDigest digest = java.security.MessageDigest
                      .getInstance("MD5");
              digest.update(s.getBytes());
              byte messageDigest[] = digest.digest();
      
              // Create Hex String
              StringBuffer hexString = new StringBuffer();
              for (int i = 0; i < messageDigest.length; i++)
                  hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
              return hexString.toString();
      
          } catch (NoSuchAlgorithmException e) {
              e.printStackTrace();
          }
          return "";
      }
      

      结果:1865e62e7129927f6e4cd9bff104f0(长度 30)

      工作方式:

      public static final String md5(final String toEncrypt) {
          try {
              final MessageDigest digest = MessageDigest.getInstance("md5");
              digest.update(toEncrypt.getBytes());
              final byte[] bytes = digest.digest();
              final StringBuilder sb = new StringBuilder();
              for (int i = 0; i < bytes.length; i++) {
                  sb.append(String.format("%02X", bytes[i]));
              }
              return sb.toString().toLowerCase();
          } catch (Exception exc) {
              return ""; // Impossibru!
          }
      }
      

      结果:1865e62e7129927f6e4c0d9bff1004f0(长度 32)

      【讨论】:

        【解决方案8】:

        使用@Donut 解决方案,使用UTF-8 编码字符(例如:é),您必须使用getBytes("UTF-8")。这是我对摘要方法的更正:

        private static char[] hextable = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        
        
        public static String byteArrayToHex(byte[] array) {
            String s = "";
            for (int i = 0; i < array.length; ++i) {
                int di = (array[i] + 256) & 0xFF; // Make it unsigned
                s = s + hextable[(di >> 4) & 0xF] + hextable[di & 0xF];
            }
            return s;
        }
        
        public static String digest(String s, String algorithm) {
            MessageDigest m = null;
            try {
                m = MessageDigest.getInstance(algorithm);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                return s;
            }
        
            try {
                m.update(s.getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                m.update(s.getBytes());
            }
            return byteArrayToHex(m.digest());
        }
        
        public static String md5(String s) {
            return digest(s, "MD5");
        }
        

        【讨论】:

          【解决方案9】:

          以下内容在 Android 上对我有用,而不会截断前面的任何 0:

          MessageDigest md = null;
          String digest = null;
              try {
                  md = MessageDigest.getInstance("MD5");
          
                  byte[] hash = md.digest(myStringToEncode.getBytes("UTF-8")); //converting byte array to Hexadecimal String
                  StringBuilder sb = new StringBuilder(2*hash.length);
          
                  for(byte b : hash){
                      sb.append(String.format("%02x", b&0xff));
                  }
          
                  digest = sb.toString();
          
              } catch (NoSuchAlgorithmException e) {
                  e.printStackTrace();
              } catch (UnsupportedEncodingException e) {
                  e.printStackTrace();
              }
          
          return digest;
          

          【讨论】:

            【解决方案10】:

            如果您使用的是番石榴:

            public String generateMd5(String input) {
                HashFunction hf = Hashing.md5();
                Hasher hasher = hf.newHasher();
            
                HashCode hc = hasher.putString(input, StandardCharsets.UTF_8).hash();
            
                return hc.toString();
            }
            

            【讨论】:

              【解决方案11】:

              如果您没有安全限制并且只想将 String 转换为唯一的 int。 我写它是因为我寻找并到达这里。

              String my_key
              int my_key.hashCode()
              

              如果您最多有 10 个字符,它甚至会是唯一的 也可以看看 https://stackoverflow.com/a/17583653/1984636

              【讨论】:

                【解决方案12】:

                这不是缺少'0'

                  public static String md5(String string) {
                        if (TextUtils.isEmpty(string)) {
                            return "";
                        }
                        MessageDigest md5 = null;
                        try {
                            md5 = MessageDigest.getInstance("MD5");
                            byte[] bytes = md5.digest(string.getBytes());
                            String result = "";
                            for (byte b : bytes) {
                                String temp = Integer.toHexString(b & 0xff);
                                if (temp.length() == 1) {
                                    temp = "0" + temp;
                                }
                                result += temp;
                            }
                            return result;
                        } catch (NoSuchAlgorithmException e) {
                            e.printStackTrace();
                        }
                        return "";
                    }
                

                【讨论】:

                  猜你喜欢
                  • 2011-08-24
                  • 1970-01-01
                  • 2021-09-19
                  • 2018-11-08
                  • 2014-05-13
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-01-15
                  • 2018-06-18
                  相关资源
                  最近更新 更多