将字符串转换为字节数组,然后再转回原始字符串

55

在Java或Android中,将字符串转换为字节数组,然后将其转换回原始字符串是否可能?

我的目标是将一些字符串发送到微控制器(Arduino)并将其存储到EEPROM中(仅为1 KB)。我尝试使用MD5哈希,但似乎它只是单向加密。我应该怎么处理这个问题?


如果您要将字符串发送到Arduino,请尝试使用SHA128。它是可逆的,但我不知道您是否需要在Arduino上使用该代码。 - Richard Barker
5个回答

127

我建议使用字符串的成员,但需要显式指定编码

byte[] bytes = text.getBytes("UTF-8");
String text = new String(bytes, "UTF-8");

通过使用明确的编码(并支持所有Unicode),您可以避免仅调用text.getBytes()等的问题:
  • 您明确地使用特定编码,因此您知道以后要使用哪种编码,而不是依赖于平台默认值。
  • 您知道它将支持所有Unicode(而不是ISO-Latin-1之类的编码)。
编辑:即使UTF-8是Android上的默认编码,我肯定会明确说明这一点。例如,这个问题只说“在Java或Android中” - 所以完全有可能代码最终会在其他平台上使用。
基本上,考虑到普通的Java平台可以具有不同的默认编码,我认为最好是绝对明确。我见过太多使用默认编码并且丢失数据的人,所以不想冒这个风险。
编辑:匆忙之中,我忘记提到您不必使用编码的名称 - 您可以使用Charset代替。使用Guava,我真的会使用:
byte[] bytes = text.getBytes(Charsets.UTF_8);
String text = new String(bytes, Charsets.UTF_8);

1
UTF-8 不是 Android 平台的默认编码吗? - ewanm89
1
公共静态字符集 defaultCharset() 自:API级别1返回系统的默认字符集。这是在VM启动期间确定的,并且此后不会更改。在Android上,默认字符集为UTF-8。 - ewanm89
1
@ewanm89:嗯,问题说“在Java或Android中”-无论如何我个人都会明确说明,因为在其他Java平台上它并不总是默认的。这样做会使代码与(比方说)一个servlet共享变得过于容易,然后得到错误的结果。 - Jon Skeet
1
如果你在使用安卓系统,你可以使用StandardCharsets.UTF_8。 - Ayyappa

16

3
我绝对不会使用那段代码。它假设平台默认编码在两个地方使用时相同,并且假定平台默认编码可以处理字符串中的所有字符。 - Jon Skeet
Android的默认字符集是UTF-8,这与您建议的相同,所以实际上没有不使用它的理由。如果您要使用其他类型的编码,您应该使用您的建议中的代码,并稍微调整一下来适应任何您正在使用的字符集。 - Michell Bak
无论如何,我仍然会明确说明。请查看我刚刚在自己的答案中留下的评论,我也会将其编辑到答案中。 - Jon Skeet
我同意你对Java的一般评论,但在Android中这没有任何意义。为什么要明确写出一些已经默认设置的内容呢?这毫无意义。 - Michell Bak
1
因为这只是Android中的默认设置,很容易将代码复制到Servlet中而没有意识到它引入了一个错误。你能看到这种情况发生吗?我至少会写一个注释,说明这在Android上保证使用UTF-8,但在其他平台上不能保证。那个注释会比明确指定编码要长得多... - Jon Skeet

3
使用 [String.getBytes()][1] 将其转换为字节数组,然后使用 [String(byte[] data)][2] 构造函数将其转换回字符串。

3
如果没有指定编码方式,不要使用这两种编码方式之一,否则你将使用平台默认的编码方式,这种编码方式可能无法支持你字符串中的所有字符。 - Jon Skeet

0
import java.io.FileInputStream;
import java.io.ByteArrayOutputStream;

public class FileHashStream 
{
    // write a new method that will provide a new Byte array, and where this generally reads from an input stream
    
    public static byte[] read(InputStream is) throws Exception
    {
        String path = /* type in the absolute path for the 'commons-codec-1.10-bin.zip' */;

        // must need a Byte buffer

        byte[] buf = new byte[1024 * 16]

        // we will use 16 kilobytes

        int len = 0;

        // we need a new input stream

        FileInputStream is = new FileInputStream(path);

        // use the buffer to update our "MessageDigest" instance

        while(true)
        {
            len = is.read(buf);
            if(len < 0) break;
            md.update(buf, 0, len);
        }

        // close the input stream

        is.close();

        // call the "digest" method for obtaining the final hash-result

        byte[] ret = md.digest();

        System.out.println("Length of Hash: " + ret.length);

        for(byte b : ret)
        {
            System.out.println(b + ", ");
        }

        String compare = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";

        String verification = Hex.encodeHexString(ret);

        System.out.println();

        System.out.println("===")

        System.out.println(verification);

        System.out.println("Equals? " + verification.equals(compare));
            
    }
}

0

byte [] pdfBytes = Base64.decode(myPdfBase64String,Base64.DEFAULT)


4
您的回答可以通过添加更多支持性信息进行改进。请编辑以添加更多细节,例如引用或文档,以便其他人可以确认您的答案是否正确。您可以在帮助中心中找到有关撰写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接