byte数组转为char数组 |
您所在的位置:网站首页 › byte转成char › byte数组转为char数组 |
我正在寻找将Java char数组转换为字节数组而不创建中间String的方法,因为char数组包含密码。 我查看了几种方法,但是它们似乎都失败了: char[] password ="password".toCharArray(); byte[] passwordBytes1 = new byte[password.length*2]; ByteBuffer.wrap(passwordBytes1).asCharBuffer().put(password); byte[] passwordBytes2 = new byte[password.length*2]; for(int i=0; i passwordBytes2[2*i] = (byte) ((password[i]&0xFF00)>>8); passwordBytes2[2*i+1] = (byte) (password[i]&0x00FF); } String passwordAsString = new String(password); String passwordBytes1AsString = new String(passwordBytes1); String passwordBytes2AsString = new String(passwordBytes2); System.out.println(passwordAsString); System.out.println(passwordBytes1AsString); System.out.println(passwordBytes2AsString); assertTrue(passwordAsString.equals(passwordBytes1) || passwordAsString.equals(passwordBytes2)); 断言总是失败的(并且,至关重要的是,当在生产中使用该代码时,密码被拒绝),但是print语句会打印出三次密码。 为什么passwordBytes1AsString和passwordBytes2AsString与passwordAsString不同,却显得相同? 我是否错过了空终止符之类的东西? 我怎样做才能使转换和未转换工作? 为什么要避免创建中间字符串? Sun建议将它作为最佳实践:download.oracle.com/javase/1.5.0/docs/guide/security/jce/字符串是不可变的,因此不能像char数组一样清零-相反,您的密码在内存中徘徊, 不确定的时间。 char和byte之间的转换是字符集的编码和解码。我更喜欢在代码中尽可能地使其清晰。这实际上并不意味着额外的代码量: Charset latin1Charset = Charset.forName("ISO-8859-1"); charBuffer = latin1Charset.decode(ByteBuffer.wrap(byteArray)); // also decode to String byteBuffer = latin1Charset.encode(charBuffer); // also decode from String 在旁边: java.nio类和java.io Reader / Writer类使用ByteBuffer和CharBuffer(它们使用byte []和char []作为后备数组)。因此,通常最好直接使用这些类。但是,您始终可以执行以下操作: byteArray = ByteBuffer.array(); byteBuffer = ByteBuffer.wrap(byteArray); byteBuffer.get(byteArray); charBuffer.put(charArray); charArray = CharBuffer.array(); charBuffer = ByteBuffer.wrap(charArray); charBuffer.get(charArray); charBuffer.put(charArray); 问题是您使用String(byte[])构造函数,该构造函数使用平台默认编码。这几乎从来都不是您应该做的-如果您通过" UTF-16"作为字符编码正常工作,则测试可能会通过。目前,我怀疑passwordBytes1AsString和passwordBytes2AsString的长度均为16个字符,其他每个字符均为U + 0000。 我只是尝试了(即String passwordBytes1AsString = new String(passwordBytes1,"UTF-16");)而没有任何变化。我还尝试检查字符串的长度-String.length()返回8。它将计算U + 0000个字符吗? @Scott:尝试打印出字符串的长度以及各个字符(作为int值)。 Thatll向您显示差异之处。 原始版本和转换版本都为112,97,115,115,119,111,114,100。 @斯科特:在那种情况下,断言现在应该过去了... 刚刚注意到我在断言中对equals()使用了错误的参数。 * facepalm *您最初的假设确实是正确的。非常感谢。 原始答案 public byte[] charsToBytes(char[] chars){ Charset charset = Charset.forName("UTF-8"); ByteBuffer byteBuffer = charset.encode(CharBuffer.wrap(chars)); return Arrays.copyOf(byteBuffer.array(), byteBuffer.limit()); } public char[] bytesToChars(byte[] bytes){ Charset charset = Charset.forName("UTF-8"); CharBuffer charBuffer = charset.decode(ByteBuffer.wrap(bytes)); return Arrays.copyOf(charBuffer.array(), charBuffer.limit()); } 编辑以使用StandardCharsets public byte[] charsToBytes(char[] chars) { final ByteBuffer byteBuffer = StandardCharsets.UTF_8.encode(CharBuffer.wrap(chars)); return Arrays.copyOf(byteBuffer.array(), byteBuffer.limit()); } public char[] bytesToChars(byte[] bytes) { final CharBuffer charBuffer = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)); return Arrays.copyOf(charBuffer.array(), charBuffer.limit()); } 这是StandardCharsets的JavaDoc页面。 在JavaDoc页面上注意这一点: These charsets are guaranteed to be available on every implementation of the Java platform. 很好地使用ByteBuffer。但是,如果没有另外说明,密码是Unicode,因此StandardCharset.UTF_8优于通过将数据简化为ASCII来破坏数据。 您可以使用所需的任何字符集 我的观点是,ASCII通常是错误的。 我编辑了从US-ASCII更改为UTF-8的帖子。你是对的。想法是保持相同的编码。例如,US-ASCII的字符数不及UTF-8的字符数-没有带重音符号的字母,如果使用的是第一个UTF-8,然后使用US-ASCII,则会丢失一些信息。 将敏感数据存储在char []或byte []中后,您需要清除敏感数据,如Andrii在此处说明的用法一样stackoverflow.com/a/9670279/1582089 很好的例子。但就我而言,它可以与Charset charset = Charset.forName(" ISO-8859-1");一起使用。 我要做的是使用一个循环将其转换为字节,然后将另一个转换为char。 char[] chars ="password".toCharArray(); byte[] bytes = new byte[chars.length*2]; for(int i=0;i bytes[i*2] = (byte) (chars[i] >> 8); bytes[i*2+1] = (byte) chars[i]; } char[] chars2 = new char[bytes.length/2]; for(int i=0;i chars2[i] = (char) ((bytes[i*2] int length = chars.length; byte[] result = new byte[length*2+2]; int i = 0; for(int j = 0 ;j result[i++] = (byte)( (chars[j] & 0xFF00) >> 8 ); result[i++] = (byte)((chars[j] & 0x00FF)) ; } return result; } 用途: String sample ="abc"; //First get the chars of the String,each char has two bytes(Java). Char[] sample_chars = sample.toCharArray(); //Get the bytes byte[] result = charArray2ByteArray(sample_chars). //Back to String. //Make sure we use UTF_16BE. Because we read the memory of Unicode of //the String from Left to right. That's the same reading //sequece of UTF-16BE. String sample_back= new String(result , StandardCharsets.UTF_16BE); 这个问题没有提到getBytes,所以这并没有真正的意义。您是否要评论其他答案之一? 只想声明String的getBytes函数的用法。并且在使用new String(Byte [])时应该注意什么。希望能帮助到你。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |