programing

바이트 어레이를 문자열로 변환하거나 그 반대로 변환하는 방법

goodsources 2022. 8. 8. 20:06
반응형

바이트 어레이를 문자열로 변환하거나 그 반대로 변환하는 방법

Android에서 바이트 배열을 문자열로 변환해야 하는데 바이트 배열에 음수 값이 포함되어 있습니다.

이 문자열을 다시 바이트 배열로 변환하면 가져올 값이 원래 바이트 배열 값과 다릅니다.

적절한 변환을 하려면 어떻게 해야 하나요?변환에 사용하는 코드는 다음과 같습니다.

// Code to convert byte arr to str:
byte[] by_original = {0,1,-2,3,-4,-5,6};
String str1 = new String(by_original);
System.out.println("str1 >> "+str1);

// Code to convert str to byte arr:
byte[] by_new = str1.getBytes();
for(int i=0;i<by_new.length;i++) 
System.out.println("by1["+i+"] >> "+str1);

나는 이 문제에 빠져 있다.

바이트 배열에 인코딩이 있어야 합니다.음수 값이 있는 경우 인코딩은 ASCII일 수 없습니다.이를 파악하면 다음과 같이 바이트 집합을 문자열로 변환할 수 있습니다.

byte[] bytes = {...}
String str = new String(bytes, StandardCharsets.UTF_8); // for UTF-8 encoding

사용할 수 있는 인코딩이 많이 있습니다. Oracle javadoc에서 지원되는 인코딩을 확인하십시오.

사이의 '적절한 변환'byte[]그리고.String사용하는 인코딩을 명시적으로 기술하는 것입니다.먼저 a로 시작하는 경우byte[]실제로 텍스트 데이터가 포함되어 있지 않으며 "적절한 변환"도 없습니다. String는 텍스트용입니다.byte[]바이너리 데이터를 위한 것입니다.또한 필요한 경우가 아니면 바이너리 데이터를 변환하지 않도록 하는 것이 가장 현명한 방법입니다.

꼭 사용해야 하는 경우String바이너리 데이터를 보관 유지하는 가장 안전한 방법은 Base64 인코딩을 사용하는 것입니다.

근본적인 문제는 다음과 같은 문자 집합을 무의식적으로 사용하고 있다는 것입니다.

 bytes != encode(decode(bytes))

경우에 따라서는.UTF-8은 이러한 문자 집합의 예입니다.구체적으로 바이트의 특정 시퀀스는 UTF-8에서 유효한 인코딩이 아닙니다.UTF-8 디코더는 이러한 시퀀스 중 하나를 검출하면 문제의 바이트를 폐기하거나 "no scheat character"의 Unicode 코드 포인트로 디코딩할 가능성이 있습니다.자연스럽게 문자를 바이트로 인코딩하려고 하면 결과가 달라집니다.

해결책은 다음과 같습니다.

  1. 사용 중인 문자 인코딩에 대해 명시적이어야 합니다. 즉, String 생성자와String.toByteArray명시적인 문자 집합이 있는 메서드.
  2. 바이트 데이터에 적합한 문자 집합 사용...또는 (모든 바이트시퀀스가 유효한 Unicode 문자에 매핑되는 "Latin-1" 등)을 지정합니다.
  3. 바이트가 (실제) 바이너리 데이터이고 "텍스트 기반" 채널을 통해 바이트를 송수신하려면 Base64 인코딩과 같은 것을 사용합니다.이 목적을 위해 설계된 것입니다.

Java의 경우 가장 일반적인 문자 집합은 에 있습니다.Unicode 문자 값을 포함할 수 있는 문자열을 인코딩하는 경우 UTF-8 인코딩()UTF_8을 권장합니다.

Java에서 1:1 매핑을 원하는 경우 ISO Latin Alphabet No.1(일반적으로 "Latin 1" 또는 단순히 "Latin")ISO_8859_1사용할 수 있습니다.Java의 Latin-1은 컨트롤 블록 C0 및 C1을 포함한 가능한 모든 256개의 값에 문자를 할당하는 Latin-1의 IANA 버전입니다.이것들은 인쇄할 수 없습니다.어느 출력에도 표시되지 않습니다.

8 에는 Java 8이 포함되어 있습니다.java.util.Base64Base64 부호화/복호화의 경우.URL 안전 부호화에서는 표준 인코더 대신 사용할 수 있습니다.이 클래스는 Android Oreo (8) API 레벨 26 이후 Android에도 존재합니다.

는 단지 것을 .String어레이: http://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/

String s = new String(bytes);

결과 문자열의 바이트는 사용하는 문자 집합에 따라 달라집니다.new String(바이트) 및 new String(바이트, Charset).forName("utf-8") 및 새로운 String(바이트, 문자 집합)을 지정합니다.string #getBytes()를 호출하면(기본 문자 집합에 따라 다름) forName("utf-16")의 바이트 배열이 모두 다릅니다.

「」를 사용합니다.new String(byOriginal)「」로 합니다.byte[]를 사용합니다.getBytes() 개의 2개의 2개의 2개의 2인 2조의 byte[]같은 가치로.이것은, 에 의해서 부호화 되는 콜에 의한 것입니다.String이 부호화중에, 인코더는 불명확한 문자를 치환하거나 그 외의 변경을 실시하도록 선택할 수 있습니다.이 때문에,String.getBytes()당신이 원래 생성자에 전달된 동등한 배열을 반환하지 않을까.는 처음에 컨스트럭터에 전달된 것과 동일한 배열을 반환하지 않을 수 있습니다.

문제가 발생한 이유:이미 지정한 대로:바이트[]로 시작하고 실제로 텍스트 데이터가 포함되지 않으면 "올바른 변환"이 없습니다. 문자열은 텍스트용, 바이트[]는 바이너리 데이터용입니다.필요한 경우가 아니면 이들 사이의 변환을 피하는 것이 유일한 방법입니다.

pdf 파일에서 바이트[]를 생성하여 String으로 변환하고 String을 입력으로 사용하여 파일로 변환할 때 이 문제가 발견되었습니다.

그러니까 당신의 부호화 및 복호화 논리가 나와 같은지 확인하세요.바이트[]를 Base64로 명시적으로 부호화하고 디코딩하여 파일을 다시 만듭니다.

사용 사례:몇 가지 제한 사항 때문에 보내려고 했습니다.byte[]에에request(POST)로:그과정은 다음과 같습니다 다음 그리고 이 과정이었다.

PDF 파일>> Base64.encodeBase64(byte[]>> String >> Send in request(POST)> receive String >> Base64.decodeBase64(byte[]>> 바이너리 작성

이걸 써보고 이게 먹혔어.

File file = new File("filePath");

        byte[] byteArray = new byte[(int) file.length()];

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            fileInputStream.read(byteArray);

            String byteArrayStr= new String(Base64.encodeBase64(byteArray));

            FileOutputStream fos = new FileOutputStream("newFilePath");
            fos.write(Base64.decodeBase64(byteArrayStr.getBytes()));
            fos.close();
        } 
        catch (FileNotFoundException e) {
            System.out.println("File Not Found.");
            e.printStackTrace();
        }
        catch (IOException e1) {
            System.out.println("Error Reading The File.");
            e1.printStackTrace();
        }

그럼에도 불구하고.

new String(bytes, "UTF-8")

그것은 맞습니까를 throw 합니다 맞습니까?UnsupportedEncodingException너는 확인된 예외를 처리하도록 강요한다.체크된예외를 처리해야 합니다.이후 자바 1.6Java가 1.6이후 다른에 바이트 배열 생성자로바이트 배열을 변환하여를 변환하는 데 당신은 대안으로 다른 생성자를 사용할 수 있다.String:

new String(bytes, StandardCharsets.UTF_8)

이건 예외는 없어요.

변환 다시 또한다시 변환하는 작업도다음과같이 수행해야 합니다에 이루어져야 한다.StandardCharsets.UTF_8:

"test".getBytes(StandardCharsets.UTF_8)

다시 한 번 체크된 예외를 처리할 필요가 없습니다.

private static String toHexadecimal(byte[] digest){
        String hash = "";
    for(byte aux : digest) {
        int b = aux & 0xff;
        if (Integer.toHexString(b).length() == 1) hash += "0";
        hash += Integer.toHexString(b);
    }
    return hash;
}

나는 어느 대답에도 없는 것을 알아차렸다.바이트 배열의 각 바이트를 문자로 캐스트하여 char 배열에 넣을 수 있습니다.그럼 문자열은

new String(cbuf)
where cbuf is the char array. To convert back, loop through the string casting each of the chars to bytes to put into a byte array, and this byte array will be the same as the first.


public class StringByteArrTest {

    public static void main(String[] args) {
        // put whatever byte array here
        byte[] arr = new byte[] {-12, -100, -49, 100, -63, 0, -90};
        for (byte b: arr) System.out.println(b);
        // put data into this char array
        char[] cbuf = new char[arr.length];
        for (int i = 0; i < arr.length; i++) {
            cbuf[i] = (char) arr[i];
        }
        // this is the string
        String s = new String(cbuf);
        System.out.println(s);

        // converting back
        byte[] out = new byte[s.length()];
        for (int i = 0; i < s.length(); i++) {
            out[i] = (byte) s.charAt(i);
        }
        for (byte b: out) System.out.println(b);
    }

}

이것으로 충분합니다.

String cd = "Holding some value";

문자열에서 바이트[]로 변환하고 있습니다.

byte[] cookie = new sun.misc.BASE64Decoder().decodeBuffer(cd);

바이트[]에서 문자열로 변환:

cd = new sun.misc.BASE64Encoder().encode(cookie);

javax.xml.bind.DatatypeConverter그것이 수행해야 합니다.다음 작업을 수행합니다.

byte [] b = javax.xml.bind.DatatypeConverter.parseHexBinary("E62DB");
String s = javax.xml.bind.DatatypeConverter.printHexBinary(b);

바이트 배열을 문자열로 변환하는 방법을 몇 가지 소개합니다.잘 작동하는지 테스트해 봤어요.

public String getStringFromByteArray(byte[] settingsData) {

    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(settingsData);
    Reader reader = new BufferedReader(new InputStreamReader(byteArrayInputStream));
    StringBuilder sb = new StringBuilder();
    int byteChar;

    try {
        while((byteChar = reader.read()) != -1) {
            sb.append((char) byteChar);
        }
    }
    catch(IOException e) {
        e.printStackTrace();
    }

    return sb.toString();

}

public String getStringFromByteArray(byte[] settingsData) {

    StringBuilder sb = new StringBuilder();
    for(byte willBeChar: settingsData) {
        sb.append((char) willBeChar);
    }

    return sb.toString();

}

base64 인코딩은 안전하고 "정답"이라고 주장할 수 있지만, 저는 Java 바이트 배열을 그대로 Java String으로 변환하는 방법을 찾고 있었습니다.즉, 바이트 배열의 각 멤버는 String 대응에 그대로 남아 인코딩/전송에 여분의 공간이 필요하지 않습니다.

8비트 투명 인코딩을 설명하는 이 답변은 저에게 큰 도움이 되었습니다.나는 사용했다ISO-8859-1이진 데이터의 테라 바이트에 앞뒤로 성공적으로 부풀어 오른 공간 요구 사항은 base64 인코딩에 필요한 없이(이진<>->, String), 그래서 내 use-case가 안전하다는 것이다-YMMV.Base64 인코딩에 필요한 확장 공간 요건 없이(2진수<>->, String)변환이 성공적이기 때문에사용 예:YMMV에 안전합니다 변환할입니다.

이것은 실험을 해야 하는 시기를 설명하는 데도 도움이 되었습니다.

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;    

private static String base64Encode(byte[] bytes)
{
    return new BASE64Encoder().encode(bytes);
}

private static byte[] base64Decode(String s) throws IOException
{
    return new BASE64Decoder().decodeBuffer(s);
}

다음 방법으로 바이트 배열을 문자열로 변환했습니다.

public static String byteArrayToString(byte[] data){
    String response = Arrays.toString(data);

    String[] byteValues = response.substring(1, response.length() - 1).split(",");
    byte[] bytes = new byte[byteValues.length];

    for (int i=0, len=bytes.length; i<len; i++) {
        bytes[i] = Byte.parseByte(byteValues[i].trim());
    }

    String str = new String(bytes);
    return str.toLowerCase();
}

이것은 Android까지 사용할 수 있습니다.Q :

다음 방법을 사용하여 16진수 문자열을 문자열로 변환할 수 있습니다.

    public static String hexToString(String hex) {
    StringBuilder sb = new StringBuilder();
    char[] hexData = hex.toCharArray();
    for (int count = 0; count < hexData.length - 1; count += 2) {
        int firstDigit = Character.digit(hexData[count], 16);
        int lastDigit = Character.digit(hexData[count + 1], 16);
        int decimal = firstDigit * 16 + lastDigit;
        sb.append((char)decimal);
    }
    return sb.toString();
}

바이트 배열을 16진수 문자열로 변환하려면 다음과 같이 입력합니다.

    public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for (int j = 0; j < bytes.length; j++) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

여기 작업 코드가 있습니다.

            // Encode byte array into string . TemplateBuffer1 is my bytearry variable.

        String finger_buffer = Base64.encodeToString(templateBuffer1, Base64.DEFAULT);
        Log.d(TAG, "Captured biometric device->" + finger_buffer);


        // Decode String into Byte Array. decodedString is my bytearray[] 
        decodedString = Base64.decode(finger_buffer, Base64.DEFAULT);

변환에는 루프를 심플하게 사용할 수 있습니다.

public void byteArrToString(){
   byte[] b = {'a','b','$'};
   String str = ""; 
   for(int i=0; i<b.length; i++){
       char c = (char) b[i];
       str+=c;
   }
   System.out.println(str);
}
byte[] image = {...};
String imageString = Base64.encodeToString(image, Base64.NO_WRAP);

다음을 수행하여 바이트 배열을 문자열로 변환한 다음 해당 문자열을 바이트 배열로 변환할 수 있습니다.

// 1. convert byte array to string and then string to byte array

    // convert byte array to string
    byte[] by_original = {0, 1, -2, 3, -4, -5, 6};
    String str1 = Arrays.toString(by_original);
    System.out.println(str1); // output: [0, 1, -2, 3, -4, -5, 6]

    // convert string to byte array
    String newString = str1.substring(1, str1.length()-1);
    String[] stringArray = newString.split(", ");
    byte[] by_new = new byte[stringArray.length];
    for(int i=0; i<stringArray.length; i++) {
        by_new[i] = (byte) Integer.parseInt(stringArray[i]);
    }
    System.out.println(Arrays.toString(by_new)); // output: [0, 1, -2, 3, -4, -5, 6]

그러나 문자열을 바이트 배열로 변환하고 해당 바이트 배열을 문자열로 변환하려면 다음 방법을 사용할 수 있습니다.

// 2. convert string to byte array and then byte array to string

    // convert string to byte array
    String str2 = "[0, 1, -2, 3, -4, -5, 6]";
    byte[] byteStr2 = str2.getBytes(StandardCharsets.UTF_8);
    // Now byteStr2 is [91, 48, 44, 32, 49, 44, 32, 45, 50, 44, 32, 51, 44, 32, 45, 52, 44, 32, 45, 53, 44, 32, 54, 93]

    // convert byte array to string
    System.out.println(new String(byteStr2, StandardCharsets.UTF_8)); // output: [0, 1, -2, 3, -4, -5, 6]

두 변환 모두 8비트 문자 집합을 지정해 보십시오.예를 들어 ISO-8859-1.

바이트 읽기에서 바이트를 읽어라String사용을 사용하여.ByteArrayInputStream그리고 포장해서와 포장해BufferedReader바이트 데이터를 문자열로 변환하는 바이트 스트림 대신 Char Stream입니다.

package com.cs.sajal;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

public class TestCls {

    public static void main(String[] args) {

        String s=new String("Sajal is  a good boy");

        try
        {
        ByteArrayInputStream bis;
        bis=new ByteArrayInputStream(s.getBytes("UTF-8"));

        BufferedReader br=new BufferedReader(new InputStreamReader(bis));
        System.out.println(br.readLine());

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

    }
}

출력:

사잘은 착한 아이야

문자열은 문자 집합입니다(16비트 부호 없음).따라서 음수를 문자열로 변환할 경우 변환 시 손실됩니다.

public class byteString {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        String msg = "Hello";
        byte[] buff = new byte[1024];
        buff = msg.getBytes("UTF-8");
        System.out.println(buff);
        String m = new String(buff);
        System.out.println(m);


    }

}

언급URL : https://stackoverflow.com/questions/1536054/how-to-convert-byte-array-to-string-and-vice-versa

반응형