मैं जावा में एक चरित्र सरणी को बाइट सरणी में बदलना चाहूंगा। इस रूपांतरण को बनाने के लिए क्या तरीके मौजूद हैं?
मैं जावा में एक चरित्र सरणी को बाइट सरणी में बदलना चाहूंगा। इस रूपांतरण को बनाने के लिए क्या तरीके मौजूद हैं?
जवाबों:
char[] ch = ?
new String(ch).getBytes();
या
new String(ch).getBytes("UTF-8");
गैर-डिफ़ॉल्ट चार्ट प्राप्त करने के लिए।
अद्यतन: जावा 7 के बाद से:new String(ch).getBytes(StandardCharsets.UTF_8);
Stringऑब्जेक्ट बनाए बिना कनवर्ट करें :
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import java.util.Arrays;
byte[] toBytes(char[] chars) {
CharBuffer charBuffer = CharBuffer.wrap(chars);
ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
byte[] bytes = Arrays.copyOfRange(byteBuffer.array(),
byteBuffer.position(), byteBuffer.limit());
Arrays.fill(byteBuffer.array(), (byte) 0); // clear sensitive data
return bytes;
}
उपयोग:
char[] chars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
byte[] bytes = toBytes(chars);
/* do something with chars/bytes */
Arrays.fill(chars, '\u0000'); // clear sensitive data
Arrays.fill(bytes, (byte) 0); // clear sensitive data
समाधान झूले में [] में पासवर्ड स्टोर करने की सिफारिश से प्रेरित है। (देखें क्यों char [] पासवर्ड के लिए स्ट्रिंग पर पसंद किया गया है? )
याद रखें कि लॉग करने के लिए संवेदनशील डेटा न लिखें और यह सुनिश्चित करें कि जेवीएम इसका कोई संदर्भ नहीं रखेगा।
उपरोक्त कोड सही है लेकिन प्रभावी नहीं है। यदि आपको प्रदर्शन की आवश्यकता नहीं है, लेकिन सुरक्षा चाहते हैं तो आप इसका उपयोग कर सकते हैं। अगर सुरक्षा भी एक लक्ष्य नहीं है, तो बस करो String.getBytes। यदि आप encodeJDK के कार्यान्वयन को देखते हैं तो उपरोक्त कोड प्रभावी नहीं है । इसके अलावा आपको सरणियों की प्रतिलिपि बनाने और बफ़र्स बनाने की आवश्यकता है। कन्वर्ट करने का दूसरा तरीका सभी कोड को पीछे छोड़ना हैencode (उदाहरण के लिए UTF-8 ):
val xs: Array[Char] = "A ß € 嗨 𝄞 🙂".toArray
val len = xs.length
val ys: Array[Byte] = new Array(3 * len) // worst case
var i = 0; var j = 0 // i for chars; j for bytes
while (i < len) { // fill ys with bytes
val c = xs(i)
if (c < 0x80) {
ys(j) = c.toByte
i = i + 1
j = j + 1
} else if (c < 0x800) {
ys(j) = (0xc0 | (c >> 6)).toByte
ys(j + 1) = (0x80 | (c & 0x3f)).toByte
i = i + 1
j = j + 2
} else if (Character.isHighSurrogate(c)) {
if (len - i < 2) throw new Exception("overflow")
val d = xs(i + 1)
val uc: Int =
if (Character.isLowSurrogate(d)) {
Character.toCodePoint(c, d)
} else {
throw new Exception("malformed")
}
ys(j) = (0xf0 | ((uc >> 18))).toByte
ys(j + 1) = (0x80 | ((uc >> 12) & 0x3f)).toByte
ys(j + 2) = (0x80 | ((uc >> 6) & 0x3f)).toByte
ys(j + 3) = (0x80 | (uc & 0x3f)).toByte
i = i + 2 // 2 chars
j = j + 4
} else if (Character.isLowSurrogate(c)) {
throw new Exception("malformed")
} else {
ys(j) = (0xe0 | (c >> 12)).toByte
ys(j + 1) = (0x80 | ((c >> 6) & 0x3f)).toByte
ys(j + 2) = (0x80 | (c & 0x3f)).toByte
i = i + 1
j = j + 3
}
}
// check
println(new String(ys, 0, j, "UTF-8"))
स्कैला भाषा का उपयोग करने के लिए मुझे क्षमा करें। यदि आपको इस कोड को जावा में परिवर्तित करने में समस्या है तो मैं इसे फिर से लिख सकता हूं। प्रदर्शन के बारे में हमेशा वास्तविक डेटा (उदाहरण के लिए जेएमएच के साथ) की जांच करें। यह कोड बहुत कुछ वैसा ही दिखता है जैसा आप JDK [ 2 ] और प्रोटोबॉफ़ [ 3 ] में देख सकते हैं ।
एंड्री का जवाब (लेखन के समय सबसे अधिक मतदान) थोड़ा गलत है। मैंने इसे टिप्पणी के रूप में जोड़ा होगा लेकिन मैं बहुत सम्मानित नहीं हूं।
एंड्री के जवाब में:
char[] chars = {'c', 'h', 'a', 'r', 's'}
byte[] bytes = Charset.forName("UTF-8").encode(CharBuffer.wrap(chars)).array();
सरणी के लिए कॉल () वांछित मान नहीं लौटा सकता है, उदाहरण के लिए:
char[] c = "aaaaaaaaaa".toCharArray();
System.out.println(Arrays.toString(Charset.forName("UTF-8").encode(CharBuffer.wrap(c)).array()));
उत्पादन:
[97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 0]
जैसा कि देखा जा सकता है कि एक शून्य बाइट जोड़ा गया है। इसके उपयोग से बचने के लिए निम्नलिखित हैं:
char[] c = "aaaaaaaaaa".toCharArray();
ByteBuffer bb = Charset.forName("UTF-8").encode(CharBuffer.wrap(c));
byte[] b = new byte[bb.remaining()];
bb.get(b);
System.out.println(Arrays.toString(b));
उत्पादन:
[97, 97, 97, 97, 97, 97, 97, 97, 97, 97]
जैसा कि उत्तर भी पासवर्ड का उपयोग करने के लिए कहा जाता है, यह उस सरणी को खाली करने के लायक हो सकता है जो बाइटबफ़र (सरणी () फ़ंक्शन के माध्यम से एक्सेस) का समर्थन करता है:
ByteBuffer bb = Charset.forName("UTF-8").encode(CharBuffer.wrap(c));
byte[] b = new byte[bb.remaining()];
bb.get(b);
blankOutByteArray(bb.array());
System.out.println(Arrays.toString(b));
averageBytesPerChar()1 के अलावा कुछ भी मिलता है, तो आपको त्रुटियां मिलेंगी (मुझे 1.1 मिलेंगी)। ब्याज से बाहर ओएस / आर्च क्या आप उपयोग कर रहे हैं जैसा कि मैंने डबल के साथ 1.7.0_51 और ओपनजेक 1.7.0_51 के साथ जांच की और पाया कि यह 10 वर्णों से टूटा हुआ है।
buffer.array()में toBytesसमारोह अभी भी अधिरोहित जा करने की जरूरत है, वर्तमान में केवल प्रति है।
आप एक विधि बना सकते हैं:
public byte[] toBytes(char[] data) {
byte[] toRet = new byte[data.length];
for(int i = 0; i < toRet.length; i++) {
toRet[i] = (byte) data[i];
}
return toRet;
}
उम्मीद है की यह मदद करेगा