C#에서 문자열을 바이트 배열로 변환하는 중
VB에서 C#으로 변환하는 중입니다.이 문의 구문에 문제가 있습니다.
if ((searchResult.Properties["user"].Count > 0))
{
profile.User = System.Text.Encoding.UTF8.GetString(searchResult.Properties["user"][0]);
}
다음에, 다음의 에러가 표시됩니다.
인수 1: '개체'에서 '바이트[]'로 변환할 수 없습니다.
'시스템'에 가장 적합한 오버로드 메서드가 일치합니다.Text. 부호화 중.GetString(바이트[])'에 잘못된 인수가 있습니다.
이 게시물을 기반으로 코드를 수정하려고 했지만 여전히 성공하지 못했습니다.
string User = Encoding.UTF8.GetString("user", 0);
좋은 의견이라도 있나?
이미 바이트 배열이 있는 경우 해당 바이트 배열에 어떤 유형의 인코딩을 사용했는지 알아야 합니다.
예를 들어 바이트 배열이 다음과 같이 작성된 경우:
byte[] bytes = Encoding.ASCII.GetBytes(someString);
다음과 같은 문자열로 되돌려야 합니다.
string someString = Encoding.ASCII.GetString(bytes);
상속한 코드에 바이트 배열을 작성하기 위해 사용된 인코딩이 있는 경우 사용자가 설정되어 있어야 합니다.
ㅇㅇㅇㅇㅇㅇ를 ,System.Text
using System.Text;
그럼 이 코드를 사용하세요.
string input = "some text";
byte[] array = Encoding.ASCII.GetBytes(input);
고쳐지길 바라!
부호화.기본값을 사용하면 안 됩니다...
일부 응답은 다음과 같습니다.Encoding.Default
그러나 Microsoft는 이에 대해 다음과 같이 경고합니다.
컴퓨터마다 디폴트로 다른 인코딩을 사용할 수 있으며 단일 컴퓨터에서는 기본 인코딩이 변경될 수 있습니다.기본 인코딩을 사용하여 컴퓨터 간에 스트리밍되거나 동일한 컴퓨터에서 다른 시간에 검색된 데이터를 인코딩 및 디코딩할 경우 데이터가 잘못 변환될 수 있습니다.또한 Default 속성에 의해 반환되는 인코딩은 최적의 폴백(즉, 인코딩이 완전히 엉망이 되어 다시 인코딩할 수 없습니다)을 사용하여 지원되지 않는 문자를 코드 페이지에서 지원하는 문자에 매핑합니다.따라서 기본 인코딩을 사용하지 않는 것이 좋습니다.인코딩된 바이트가 올바르게 디코딩되도록 하려면 UTF8Encoding 또는 UnicodeEncoding 등의 Unicode 인코딩을 사용해야 합니다.더 높은 수준의 프로토콜을 사용하여 인코딩 및 디코딩에 동일한 형식을 사용할 수도 있습니다.
하려면 , 「」를 합니다.Encoding.Default.WindowsCodePage
- 인코딩에는 된 클래스가 는 (1250 - CP1250)으로 취득할 수 있습니다Encoding.GetEncoding(1250)
를 참조해 주세요.
대신 UTF-8/UTF-16LE 인코딩을 사용해야 합니다.
Encoding.ASCII
가장 점수가 높은 답변은 7비트이기 때문에 제 경우에서도 동작하지 않습니다.
byte[] pass = Encoding.ASCII.GetBytes("šarže");
Console.WriteLine(Encoding.ASCII.GetString(pass)); // ?ar?e
Microsoft 의 권장 사항에 따라 주세요.
var utf8 = new UTF8Encoding();
byte[] pass = utf8.GetBytes("šarže");
Console.WriteLine(utf8.GetString(pass)); // šarže
Encoding.UTF8
사용자가 하는 것은 이며 직접 asUTF-8 인코딩을 도 있습니다.
var utf8 = Encoding.UTF8 as UTF8Encoding;
Encoding.Unicode
는 메모리 내의 문자열 표현에 널리 사용되고 있습니다.이는 고정2 바이트/글자를 사용하기 때문에 메모리 사용량이 증가해도 일정한 시간에 n번째 문자로 점프할 수 있기 때문입니다.UTF-16LE 입니다.MSVC#에서는 *.cs 파일은 디폴트로 UTF-8 BOM에 있으며 컴파일 시 문자열 상수가 UTF-16LE로 변환됩니다(@OwnagelsMagic comment 참조).단, 디폴트로 정의되어 있지 않습니다.StreamWriter 등의 많은 클래스는 UTF-8을 디폴트로 사용합니다.
...하지만 항상 사용되는 것은 아닙니다.
디폴트 부호화는 오해를 불러일으킵니다.에서 UTF-8( 코드 된 포함)과 UTF-16LENET 「」, 「」UTF-8( 「」)을 합니다.Encoding.Unicode
를 사용하여 문자열을 메모리에 저장합니다.단, Windows 에서는 실제로는 UTF8 이외의2개의 디폴트인 ANSI 코드 페이지(이전 GUI 어플리케이션의 경우)가 사용됩니다.NET) 및 OEM 코드 페이지(DOS 표준).이는 국가에 따라 다르며(예를 들어 Windows 체코 버전은 CP1250 및 CP852를 사용), Windows API 라이브러리에서 하드 코딩되는 경우가 많습니다.UTF-8을 콘솔로 설정하기만 하면chcp 65001
ping를 수 ).NET이 암묵적으로 실행해 디폴트인 것처럼 가장하고 현지화된 명령어(ping 등)를 실행하면 영어 버전으로 동작하지만 체코에서는 두부 텍스트가 표시됩니다).
제 실제 경험을 공유하겠습니다.선생님들을 위해 git 스크립트를 커스터마이즈하는 WinForms 어플리케이션을 만들었습니다.출력은 Microsoft에 의해 (굵은 글씨 텍스트가 추가된) 프로세스에서 비동기적으로 백그라운드에서 취득됩니다.
이 컨텍스트(UseShellExecute)에서 "쉘"이라는 단어는 명령 셸(예를 들어 bash 또는 sh, OEM CP)이 아닌 그래픽 셸(Windows 쉘, ANSI CP와 유사)을 나타내며, 사용자가 미국 이외의 환경에서 그래픽 애플리케이션을 실행하거나 잘못된 출력을 가진 문서를 열 수 있도록 합니다.
따라서 GUI 디폴트는 UTF-8, 프로세스 디폴트는 CP1250, 콘솔 디폴트는 852가 됩니다.UTF-8은 CP1250을 사용한다.이중 변환으로 원본 코드 페이지를 추론할 수 없는 두부 문자가 왔습니다.프로세스 스크립트에 UTF-8을 명시적으로 설정하고 메인 스레드에서 CP1250의 출력을 UTF-8로 변환하기 위해 일주일 동안 머리를 쥐어뜯었습니다.현재 동유럽에서는 작동하지만 서유럽에서는 1252를 사용합니다.는 ANSI CP와 같은 때문에 할 수 .systeminfo
또한 현지화되어 있으며 다른 메서드는 버전에 따라 다릅니다.이런 환경에서는 국가 문자를 확실하게 표시하는 것은 거의 불가능합니다.
따라서 21세기 중반까지는 "기본 코드"를 사용하지 말고 명시적으로 설정하십시오(가능한 경우 UTF-8 또는 UTF-16LE).
var result = System.Text.Encoding.Unicode.GetBytes(text);
또한 Extension Method를 사용하여 Method에 추가할 수도 있습니다.string
뭇매를 맞다
static class Helper
{
public static byte[] ToByteArray(this string str)
{
return System.Text.Encoding.ASCII.GetBytes(str);
}
}
그리고 다음과 같이 사용하세요.
string foo = "bla bla";
byte[] result = foo.ToByteArray();
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
이게 나한테 효과가 있었어
byte[] bytes = Convert.FromBase64String(textString);
반대로:
string str = Convert.ToBase64String(bytes);
Ali의 답변을 바탕으로 사용하는 인코딩을 선택적으로 전달할 수 있는 확장 방법을 권장합니다.
using System.Text;
public static class StringExtensions
{
/// <summary>
/// Creates a byte array from the string, using the
/// System.Text.Encoding.Default encoding unless another is specified.
/// </summary>
public static byte[] ToByteArray(this string str, Encoding encoding = Encoding.Default)
{
return encoding.GetBytes(str);
}
}
그리고 다음과 같이 사용하세요.
string foo = "bla bla";
// default encoding
byte[] default = foo.ToByteArray();
// custom encoding
byte[] unicode = foo.ToByteArray(Encoding.Unicode);
이것을 사용하다
byte[] myByte= System.Text.ASCIIEncoding.Default.GetBytes(myString);
다음 방법은 문자가 1바이트인 경우에만 작동합니다(기본 유니코드는 2바이트이므로 작동하지 않습니다).
public static byte[] ToByteArray(string value)
{
char[] charArr = value.ToCharArray();
byte[] bytes = new byte[charArr.Length];
for (int i = 0; i < charArr.Length; i++)
{
byte current = Convert.ToByte(charArr[i]);
bytes[i] = current;
}
return bytes;
}
심플하게
MemoryMarshal API를 사용하면 매우 빠르고 효율적인 변환을 수행할 수 있습니다. String
ReadOnlySpan<byte>
~로MemoryMarshal.Cast
중 하나를 받아들이다Span<byte>
★★★★★★★★★★★★★★★★★」ReadOnlySpan<byte>
이치노
public static class StringExtensions
{
public static byte[] ToByteArray(this string s) => s.ToByteSpan().ToArray(); // heap allocation, use only when you cannot operate on spans
public static ReadOnlySpan<byte> ToByteSpan(this string s) => MemoryMarshal.Cast<char, byte>(s);
}
다음 벤치마크에서는 그 차이를 보여 줍니다.
Input: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,"
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|----------------------------- |-----------:|----------:|----------:|-------:|------:|------:|----------:|
| UsingEncodingUnicodeGetBytes | 160.042 ns | 3.2864 ns | 6.4099 ns | 0.0780 | - | - | 328 B |
| UsingMemoryMarshalAndToArray | 31.977 ns | 0.7177 ns | 1.5753 ns | 0.0781 | - | - | 328 B |
| UsingMemoryMarshal | 1.027 ns | 0.0565 ns | 0.1630 ns | - | - | - | - |
JustinStolle 편집(Eran Yogev의 BlockCopy 사용)을 개량한 것입니다.
제안된 솔루션은 실제로 인코딩을 사용하는 것보다 더 빠릅니다.문제는 길이가 고르지 않은 바이트 배열 인코딩에는 작동하지 않는다는 것입니다.이 경우 Out-of-Bound 예외가 발생합니다.길이를 1씩 늘리면 문자열에서 디코딩할 때 후행 바이트가 남습니다.
나에게 있어, 그 필요성은 내가 인코딩하고 싶을 때 찾아왔다.DataTable
로로 합니다.JSON
문자열로 byte[]
.
때문에, 하는 때문에 와 취급하는 클래스)를 했습니다.byte[]
부호화를 실시합니다.
2진 배열의 원래 길이가 홀수('1')인지 짝수('0')인지를 나타내는 문자를 1개 추가하여 길이가 일정하지 않은 문제를 해결했습니다.
다음과 같습니다.
public static class StringEncoder
{
static byte[] EncodeToBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string DecodeToString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
}
public static class BytesEncoder
{
public static string EncodeToString(byte[] bytes)
{
bool even = (bytes.Length % 2 == 0);
char[] chars = new char[1 + bytes.Length / sizeof(char) + (even ? 0 : 1)];
chars[0] = (even ? '0' : '1');
System.Buffer.BlockCopy(bytes, 0, chars, 2, bytes.Length);
return new string(chars);
}
public static byte[] DecodeToBytes(string str)
{
bool even = str[0] == '0';
byte[] bytes = new byte[(str.Length - 1) * sizeof(char) + (even ? 0 : -1)];
char[] chars = str.ToCharArray();
System.Buffer.BlockCopy(chars, 2, bytes, 0, bytes.Length);
return bytes;
}
}
이 질문에 대한 답변은 이미 여러 번 이루어졌지만 C# 7.2와 Span 타입의 도입으로 안전하지 않은 코드로 보다 빠르게 실행할 수 있게 되었습니다.
public static class StringSupport
{
private static readonly int _charSize = sizeof(char);
public static unsafe byte[] GetBytes(string str)
{
if (str == null) throw new ArgumentNullException(nameof(str));
if (str.Length == 0) return new byte[0];
fixed (char* p = str)
{
return new Span<byte>(p, str.Length * _charSize).ToArray();
}
}
public static unsafe string GetString(byte[] bytes)
{
if (bytes == null) throw new ArgumentNullException(nameof(bytes));
if (bytes.Length % _charSize != 0) throw new ArgumentException($"Invalid {nameof(bytes)} length");
if (bytes.Length == 0) return string.Empty;
fixed (byte* p = bytes)
{
return new string(new Span<char>(p, bytes.Length / _charSize));
}
}
}
바이트는 UTF-16 부호화 스트링(C#랜드에서는 「Unicode」라고 불립니다)을 나타내는 것에 주의해 주세요.
몇 가지 간단한 벤치마킹에 따르면 위의 방법은 인코딩보다 약 5배 더 빠릅니다.유니코드GetBytes(...)/GetString(...) 실장은 중간 크기 문자열(30~50글자)에 대응하고, 큰 문자열에 대응하면 고속입니다.이 방법들은 또한 보안관에게 포인터를 사용하는 것보다 더 빠른 것으로 보인다.Copy(..) 또는 Buffer.메모리 카피(...)
결과일 경우 'searchResult.Properties [ "user " [ 0 ] ]는 문자열입니다.
if ( ( searchResult.Properties [ "user" ].Count > 0 ) ) {
profile.User = System.Text.Encoding.UTF8.GetString ( searchResult.Properties [ "user" ] [ 0 ].ToCharArray ().Select ( character => ( byte ) character ).ToArray () );
}
핵심은 문자열을 바이트 []로 변환할 수 있다는 것입니다. LINQ를 사용하면 다음과 같습니다.
.ToCharArray ().Select ( character => ( byte ) character ).ToArray () )
그리고 그 반대:
.Select ( character => ( char ) character ).ToArray () )
C#11 이전
ReadOnlySpan<byte> before = System.Text.Encoding.UTF8.GetBytes("hello!");
C# 11에서는 문자열 리터럴에 u8 서픽스를 추가하여 UTF-8로 바로 가져올 수 있습니다.
ReadOnlySpan<byte> now = "hello!"u8;
UTF-8 문자열 리터럴 관련 문서 읽기
왜 이걸 하지 말아야 하는지 아는 사람 있나요?
mystring.Select(Convert.ToByte).ToArray()
C# 11에서는 UTF-8 String Literals를 사용할 수 있습니다.이것에 의해, 매우 간단하고, 퍼포먼스가 향상해, 메모리 할당이 불필요합니다.
byte[] array = "some text";
또는 문자열 값이 이미 있는 경우:
string input = "some text";
byte[] array = input;
이것은, 낡은 방법을 사용하는 것과 다른 예를 나타내고 있습니다.UTF-8 encdoing
)GetBytes
)를 C#11에 접속합니다. UTF-8 String Literlas
웨이)GetBytesNew
를 참조해 주세요.
그 후, 이 기능을 사용하면, 데이타베이스의 바이트 필드에 화상을 변환할 수 있습니다.
using (MemoryStream s = new MemoryStream(DirEntry.Properties["thumbnailphoto"].Value as byte[]))
{
return s.ToArray();
}
이것은 꽤 많은 답을 얻었지만, 나에게 유일한 방법은 다음과 같습니다.
public static byte[] StringToByteArray(string str)
{
byte[] array = Convert.FromBase64String(str);
return array;
}
고마워 파벨 마가
다음과 같이 공헌을 완료할 수 있습니다.
public static byte[] ToByteArray(this string s) => s.ToByteSpan().ToArray();
public static string FromByteArray(this byte[] bytes) => ToCharSpan(new ReadOnlySpan<byte>(bytes)).ToString();
public static ReadOnlySpan<byte> ToByteSpan(this string str) => MemoryMarshal.Cast<char, byte>(str);
public static ReadOnlySpan<char> ToCharSpan(this ReadOnlySpan<byte> bytes) => MemoryMarshal.Cast<byte, char>(bytes);
언급URL : https://stackoverflow.com/questions/16072709/converting-string-to-byte-array-in-c-sharp
'programing' 카테고리의 다른 글
데이터베이스 인덱스는 어떻게 작동합니까? (0) | 2023.04.14 |
---|---|
#temptable과 #TempTable의 차이점 (0) | 2023.04.14 |
@size와 @dynamic의 차이점은 무엇입니까? (0) | 2023.04.14 |
버튼 클릭 이벤트에 매개 변수 추가 (0) | 2023.04.14 |
iPhone의 내비게이션 바에서 '뒤로' 버튼을 숨기는 방법 (0) | 2023.04.14 |