කේතීකරණයක් අතින් නියම නොකර C # හි නූල්වල ස්ථාවර බයිට් නිරූපණයක් ලබා ගන්නේ කෙසේද?


2194

කොහොමද මම පරිවර්තනය කරන්නේ stringවෙතbyte[] අතින් නිශ්චිත කේතන නියම තොරව .NET (C #) හි?

මම නූල සංකේතනය කිරීමට යන්නෙමි. පරිවර්තනය නොකර මට එය සංකේතනය කළ හැකිය, නමුත් කේතනාංකනය මෙහි වාදනය වීමට හේතුව දැන ගැනීමට මම තවමත් කැමතියි.

එසේම, කේතීකරණය පවා සැලකිල්ලට ගත යුත්තේ ඇයි? නූල් ගබඩා කර ඇති බයිට් මොනවාදැයි මට සරලව ලබා ගත නොහැකිද? අක්ෂර කේතීකරණ මත යැපීමක් පවතින්නේ ඇයි?


23
සෑම නූලක්ම බයිට් සමූහයක් ලෙස ගබඩා කර තිබේද? ඇයි මට ඒ බයිට් ගන්න බැරි?
ඇග්නෙල් කුරියන්

135
කේතීකරණය යනු අක්ෂර බයිට් වලට සිතියම් ගත කිරීමයි. උදාහරණයක් ලෙස, ASCII හි, 'A' අක්ෂරය අංක 65 ට අනුරූපණය වේ. වෙනත් කේතන ක්‍රමයකදී එය සමාන නොවිය හැකිය. .NET රාමුව තුළ ගෙන ඇති නූල් සඳහා ඉහළ මට්ටමේ ප්‍රවේශය මෙය බොහෝ දුරට අදාල නොවේ, නමුත් (මෙම අවස්ථාව හැර).
ලූකස් ජෝන්ස්

20
යක්ෂයාගේ අධිනීති play යා ලෙස සෙල්ලම් කිරීමට: ඔබට මතකයේ ඇති නූලක බයිට් ලබා ගැනීමට අවශ්‍ය නම් (.NET ඒවා භාවිතා කරන පරිදි) ඒවා කෙසේ හෝ හැසිරවිය යුතුය (එනම් CRC32), සහ කිසි විටෙකත් එය නැවත මුල් නූලට විකේතනය කිරීමට අවශ්‍ය නොවීය ... එය ඔබ කේතන ක්‍රම ගැන සැලකිලිමත් වන්නේ ඇයිද යන්න හෝ ඔබ භාවිතා කළ යුත්තේ කුමක්ද යන්න තෝරා ගන්නේ කෙසේද යන්න කෙලින්ම ඉදිරියට නොවේ.
ග්‍රෙග්

79
පුදුමයට පත් කිසිවෙකු තවමත් මෙම සබැඳිය ලබා දී නැත: joelonsoftware.com/articles/Unicode.html
බෙවන්

28
වර්‍ගයක් බයිට් එකක් නොවන අතර බයිට් වර්‍ගයක් නොවේ. වර්‍ගයක් යනු අකුරු වගුවකට යතුරක් සහ ශබ්දකෝෂ සම්ප්‍රදායකි. නූලක් යනු අක්ෂර මාලාවකි. (වචන, ඡේද, වාක්‍ය සහ මාතෘකා වලට ඔවුන්ගේම ආකාරයේ අර්ථකථන යුක්ති සහගත කරන ඔවුන්ගේම ශබ්දකෝෂ සම්ප්‍රදායන් ඇත - නමුත් මම කණගාටු වෙමි). නිඛිල, පාවෙන ලක්ෂ්‍ය අංක සහ අනෙක් සියල්ල මෙන් අක්ෂර බයිට් වලට කේතනය කර ඇත. කේතන ක්‍රමය එකින් එක සරල වූ කාලයක් තිබුණි: ASCII. කෙසේ වෙතත්, සියලු මානව සංකේත වලට අනුගත වීම සඳහා, බයිට් එකක ප්‍රේරණයන් 256 ප්‍රමාණවත් නොවූ අතර තෝරාගත් වැඩි බයිට් ප්‍රමාණයක් භාවිතා කිරීම සඳහා කේතීකරණ සකස් කරන ලදී.
ජෝර්ජ්

Answers:


1856

මෙහි පිළිතුරු විරුද්ධයි, ඔබ සංකේතවත් ගැන කරදර විය යුතු නැත නම් එම බයිට් පරිවර්ථනය කළ යුතු අවශ්ය නැහැ!

ඔබ සඳහන් කළාක් මෙන්, ඔබේ ඉලක්කය වන්නේ, “නූල් ගබඩා කර ඇති බයිට් මොනවාද යන්න” යන්නයි .
(ඇත්ත වශයෙන්ම, බයිට් වලින් නූල් නැවත තැනීමට හැකිවීම.)

එම අරමුණු සඳහා, මම අවංකව කරන්න නොවේ ඔබට කේතීකරණ අවශ්‍ය යැයි මිනිසුන් නොකඩවාම පවසන්නේ මන්දැයි . මේ සඳහා කේතන ක්‍රම ගැන ඔබ කරදර විය යුතු නැත.

ඒ වෙනුවට මෙය කරන්න:

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;
}

// Do NOT use on arbitrary bytes; only use on GetBytes's output on the SAME system
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);
}

ඔබේ වැඩසටහන (හෝ වෙනත් වැඩසටහන්) කෙසේ හෝ බයිට් අර්ථ නිරූපණය කිරීමට උත්සාහ නොකරන තාක් කල් , ඔබ එය කිරීමට අදහස් කරන බව ඔබ පැහැදිලිවම සඳහන් නොකළේ නම්, කිසිවක් නැත මෙම ප්‍රවේශයේ වරදක් ! කේතීකරණ ගැන කරදර වීම සැබෑ හේතුවක් නොමැතිව ඔබේ ජීවිතය වඩාත් සංකීර්ණ කරයි.

මෙම ප්‍රවේශයට අමතර ප්‍රතිලාභ:

නූලෙහි අවලංගු අක්ෂර අඩංගු වේ නම් කමක් නැත, මන්ද ඔබට තවමත් දත්ත ලබා ගත හැකි අතර මුල් නූල කෙසේ හෝ ප්‍රතිනිර්මාණය කළ හැකිය!

ඔබ බයිට් දෙස බලන නිසා එය කේතනය කර විකේතනය වනු ඇත .

ඔබ විශේෂිත කේතීකරණයක් භාවිතා කළේ නම්, අවලංගු අක්ෂර කේතනය කිරීම / විකේතනය කිරීම සම්බන්ධයෙන් එය ඔබට කරදරයක් වනු ඇත.


248
කුමක්ද මේ ගැන කැත බව, ය GetStringහා GetBytesවැඩ කිරීමට එම බොහෝ endianness සමඟ පද්ධතිය මත ක්රියාත්මක අවශ්යතාව. එබැවින් ඔබට වෙනත් තැනක නූලක් බවට පත් කිරීමට අවශ්‍ය බයිට් ලබා ගැනීමට මෙය භාවිතා කළ නොහැක. එබැවින් මට මෙය භාවිතා කිරීමට අවශ්‍ය තත්වයක් ඇතිවීමට මට අපහසුය.
කෝඩ්ස්ඉන්චෝස්

72
OdeCodeInChaos: මා කීවාක් මෙන්, මෙහි සමස්ත කරුණ වන්නේ ඔබට එය එකම ආකාරයේ පද්ධතියක් හා එකම ශ්‍රිත සමූහයක් සමඟ භාවිතා කිරීමට අවශ්‍ය නම්. එසේ නොවේ නම්, ඔබ එය භාවිතා නොකළ යුතුය.
user541686

193
-1 යමෙකුට (බයිට් එදිරිව අක්ෂර තේරෙන්නේ නැති) ඔවුන්ගේ නූල බයිට් අරා බවට පරිවර්තනය කිරීමට අවශ්‍ය බව මම සහතික කරමි, ඔවුන් එය ගූගල් කර මෙම පිළිතුර කියවනු ඇත, ඔවුන් වැරදි දේ කරනු ඇත, මන්ද සියල්ලටම පාහේ බොහෝ අවස්ථාවල දී, කේතන IS අදාළ.
artbristol

402
@artbristol: පිළිතුර (හෝ වෙනත් පිළිතුරු ...) කියවීමට ඔවුන්ට කරදර විය නොහැකි නම්, මට කණගාටුයි, එවිට ඔවුන් සමඟ සන්නිවේදනය කිරීමට මට වඩා හොඳ ක්‍රමයක් නොමැත. මගේ පිළිතුරෙන් අනෙක් අය කුමක් කළ හැකිදැයි අනුමාන කිරීමට උත්සාහ කරනවාට වඩා මම සාමාන්‍යයෙන් OP ට පිළිතුරු දීමට කැමැත්තෙමි - OP හට දැන ගැනීමට අයිතියක් ඇත, යමෙකු පිහියක් අනිසි ලෙස භාවිතා කළ හැකි නිසා එයින් අදහස් කරන්නේ අප ලෝකයේ සියලුම පිහි සැඟවිය යුතු බවයි. අප වෙනුවෙන්. ඔබ එකඟ නොවුවද එයද හොඳයි.
user541686

186
මෙම පිළිතුර බොහෝ මට්ටම් වල වැරදියි, නමුත් ප්‍රධාන වශයෙන් එය පහත වැටීම නිසා "ඔබට කේතනය කිරීම ගැන කරදර විය යුතු නැත!". GetBytes සහ GetString යන ක්‍රම දෙක අතිරික්තය, ඒවා හුදෙක් Encoding.Unicode.GetBytes () සහ Encoding.Unicode.GetString () දැනටමත් සිදු කර ඇති දේ නැවත ක්‍රියාත්මක කිරීමකි. "ඔබේ වැඩසටහන (හෝ වෙනත් වැඩසටහන්) බයිට් අර්ථ නිරූපණය කිරීමට උත්සාහ නොකරන තාක් කල්" යන ප්‍රකාශය මූලික වශයෙන් දෝෂ සහිත වන අතර එයින් ගම්‍ය වන්නේ බයිට් යුනිකෝඩ් ලෙස අර්ථ දැක්විය යුතු බවයි.
ඩේවිඩ්

1108

එය ඔබගේ නූල් කේතනය කිරීම මත රඳා පවතී ( ASCII , UTF-8 , ...).

උදාහරණයක් වශයෙන්:

byte[] b1 = System.Text.Encoding.UTF8.GetBytes (myString);
byte[] b2 = System.Text.Encoding.ASCII.GetBytes (myString);

කේතීකරණය වැදගත් වන්නේ ඇයිද යන්න කුඩා නියැදියක්:

string pi = "\u03a0";
byte[] ascii = System.Text.Encoding.ASCII.GetBytes (pi);
byte[] utf8 = System.Text.Encoding.UTF8.GetBytes (pi);

Console.WriteLine (ascii.Length); //Will print 1
Console.WriteLine (utf8.Length); //Will print 2
Console.WriteLine (System.Text.Encoding.ASCII.GetString (ascii)); //Will print '?'

ASCII හුදෙක් විශේෂ අක්ෂර සමඟ කටයුතු කිරීමට සන්නද්ධ නොවේ.

අභ්‍යන්තරව .NET රාමුව නූල් නිරූපණය කිරීම සඳහා UTF-16 භාවිතා කරයි , එබැවින් ඔබට සරලවම .NET භාවිතා කරන බයිට් ලබා ගැනීමට අවශ්‍ය නම් භාවිතා කරන්න System.Text.Encoding.Unicode.GetBytes (...).

වැඩි විස්තර සඳහා .NET Framework (MSDN) හි අක්ෂර කේතීකරණය බලන්න .


14
නමුත්, කේතන ක්‍රමය සැලකිල්ලට ගත යුත්තේ ඇයි? භාවිතා කරන්නේ කුමන කේතන ක්‍රමයක් දැයි නොදැන මට බයිට් ලබා ගත නොහැක්කේ ඇයි? එය අවශ්‍ය වුවද, භාවිතා කරන කේතන ක්‍රමය කුමක්දැයි සංගීත වස්තුව විසින්ම දැනගෙන මතකයේ ඇති දේ ඉවත දැමිය යුතු නොවේද?
ඇග්නෙල් කුරියන්

57
.NET නූල් සෑම විටම යුනිකෝඩ් ලෙස කේතනය කර ඇත. එබැවින් System.Text.Encoding.Unicode.GetBytes () භාවිතා කරන්න; අක්ෂර නිරූපණය කිරීම සඳහා .NET භාවිතා කරන බයිට් සමූහයක් ලබා ගැනීමට. කෙසේ වෙතත් ඔබට එය අවශ්‍ය වන්නේ ඇයි? බොහෝ අක්ෂර බටහිර ලතින් කට්ටලයේ ඇති විට මම UTF-8 නිර්දේශ කරමි.
ඇන්තනි ඩබ්ලිව් ජෝන්ස්

8
එසේම: නූල් වල අභ්‍යන්තරව භාවිතා කරන නිශ්චිත බයිට් ඒවා ලබා ගන්නා පද්ධතිය එම කේතීකරණය හසුරුවන්නේ නැතිනම් හෝ වැරදි කේතන ක්‍රමයක් ලෙස හසුරුවන්නේද යන්න ගැටළුවක් නොවේ . ඒ සියල්ල .Net තුළ තිබේ නම්, ඇයි කිසිසේත් බයිට් පෙළකට පරිවර්තනය වන්නේ. එසේ නොමැතිනම්, ඔබේ කේතන ක්‍රමය සමඟ පැහැදිලිව සිටීම වඩා හොඳය
ජොයෙල් කොහූර්න්

11
O ජොයෙල්, එය ක්‍රියාත්මක වන සෑම යන්ත්‍රයකම වෙනස් විය හැකි බැවින් System.Text.Encoding.Default සමඟ ප්‍රවේශම් වන්න. UTF-8 වැනි කේතීකරණයක් සෑම විටම නියම කිරීම රෙකමදාරු කරනුයේ එබැවිනි.
අළු

25
ඔබ (හෝ වෙනත් අයෙකු) සත්‍ය වශයෙන්ම දත්ත අර්ථ නිරූපණය කිරීමට අදහස් කරන්නේ නම් මිස , එය සාමාන්‍ය “බයිට් වාරණයක්” ලෙස නොසලකයි. සම්පීඩනය, ගුප්තකේතනය වැනි දේ සඳහා, කේතනය කිරීම ගැන කරදර වීම අර්ථ විරහිත ය. කේතන ක්‍රමය ගැන කරදර නොවී මෙය කළ හැකි ක්‍රමයක් සඳහා මගේ පිළිතුර බලන්න . (ඔබ එසේ නොකරන විට කේතන ක්‍රම ගැන කරදර විය යුතු යැයි පැවසීම සඳහා මම -1 ලබා දී ඇත, නමුත් අද මට විශේෂයෙන් අර්ථයක් දැනෙන්නේ නැත .: P)
user541686

285

පිළිගත් පිළිතුර ඉතා සංකීර්ණ ය. මේ සඳහා ඇතුළත් කළ .NET පන්ති භාවිතා කරන්න:

const string data = "A string with international characters: Norwegian: ÆØÅæøå, Chinese: 喂 谢谢";
var bytes = System.Text.Encoding.UTF8.GetBytes(data);
var decoded = System.Text.Encoding.UTF8.GetString(bytes);

ඔබට අවශ්‍ය නැතිනම් රෝදය ප්‍රතිනිර්මාණය නොකරන්න ...


14
පිළිගත් පිළිතුර වෙනස් වුවහොත්, වාර්තාගත අරමුණු සඳහා, එය වර්තමාන වේලාව හා දිනය අනුව මෙහර්දාඩ්ගේ පිළිතුරයි. OP විසින් මෙය නැවත සලකා බලා වඩා හොඳ විසඳුමක් පිළිගනු ඇතැයි අපේක්ෂා කරමු.
තෝමස් එඩින්ග්

8
ප්‍රතිපත්තිමය වශයෙන් හොඳයි, නමුත් කේතනය System.Text.Encoding.Unicodeකිරීම මෙහර්දාඩ්ගේ පිළිතුරට සමාන විය යුතුය.
ජොඩ්රෙල්

5
මුල් පිළිතුරේ සිට ප්‍රශ්නය බොහෝ වාර ගණනක් සංස්කරණය කර ඇත, එබැවින් මගේ පිළිතුර ටිකක් යල් පැන ගිය එකක් විය හැකිය. මම කිසි විටෙකත් මෙහර්දාඩ්ගේ පිළිතුරට සමාන ව්‍යසනයක් ලබා දීමට අදහස් කළේ නැත, නමුත් එය කිරීමට බුද්ධිමත් ක්‍රමයක් දෙන්න. නමුත්, ඔබ නිවැරදි විය හැකිය. කෙසේ වෙතත්, මුල් ප්‍රශ්නයේ "නූල ගබඩා කර ඇති බයිට් ලබා ගන්න" යන වාක්‍ය ඛණ්ඩය ඉතා අවිනිශ්චිතය. ගබඩා කර ඇත, කොහේද? මතකයේ? තැටියේ? මතකයේ තිබේ නම්, System.Text.Encoding.Unicode.GetBytesබොහෝ විට වඩාත් නිවැරදි වනු ඇත.
එරික් ඒ. බ්‍රැන්ඩ්ස්ටැඩ්මොන්

7
@ ඇමිසිකෝ, ඔබේ නූල ඔබේ පද්ධතියේ පෙරනිමි කේතන ක්‍රමයට අනුකූල බව ඔබට විශ්වාස නැත්නම් (ඔබේ පද්ධතියේ පෙරනිමි උරුමය අක්ෂර මාලාවේ ASCII අක්ෂර පමණක් අඩංගු වන නූල). නමුත් කිසිම තැනක OP එය ප්‍රකාශ නොකරයි.
ෆ්‍රෙඩ්රික්

5
@AMissico එය ක්‍රමලේඛයට විවිධ පද්ධතිවල විවිධ ප්‍රති results ල ලබා දීමට හේතු විය හැක . එය කිසි විටෙකත් හොඳ දෙයක් නොවේ. එය හැෂ් හෝ වෙනත් දෙයක් සෑදීම සඳහා වුවද (OP යනු 'සංකේතාංකනය' යන්නෙන් අදහස් කරන්නේ එයයි), එකම නූල තවමත් සෑම විටම එකම හැෂ් ලබා දිය යුතුය.
නයර්ගුඩ්ස්

114
BinaryFormatter bf = new BinaryFormatter();
byte[] bytes;
MemoryStream ms = new MemoryStream();

string orig = "喂 Hello 谢谢 Thank You";
bf.Serialize(ms, orig);
ms.Seek(0, 0);
bytes = ms.ToArray();

MessageBox.Show("Original bytes Length: " + bytes.Length.ToString());

MessageBox.Show("Original string Length: " + orig.Length.ToString());

for (int i = 0; i < bytes.Length; ++i) bytes[i] ^= 168; // pseudo encrypt
for (int i = 0; i < bytes.Length; ++i) bytes[i] ^= 168; // pseudo decrypt

BinaryFormatter bfx = new BinaryFormatter();
MemoryStream msx = new MemoryStream();            
msx.Write(bytes, 0, bytes.Length);
msx.Seek(0, 0);
string sx = (string)bfx.Deserialize(msx);

MessageBox.Show("Still intact :" + sx);

MessageBox.Show("Deserialize string Length(still intact): " 
    + sx.Length.ToString());

BinaryFormatter bfy = new BinaryFormatter();
MemoryStream msy = new MemoryStream();
bfy.Serialize(msy, sx);
msy.Seek(0, 0);
byte[] bytesy = msy.ToArray();

MessageBox.Show("Deserialize bytes Length(still intact): " 
   + bytesy.Length.ToString());

2
එම සියලු මෙහෙයුම් සඳහා ඔබට එකම ද්විමය ෆෝමැටර් උදාහරණය භාවිතා කළ හැකිය
ජොයෙල් කොහූර්න්

3
ඉතා සිත්ගන්නා සුළුය. පෙනෙන විදිහට එය ඕනෑම ඉහළ ආදේශක යුනිකෝඩ් අක්ෂරයක් අතහැර දමනු ඇත. [BinaryFormatter ] හි ලේඛනය බලන්න

95

අක්ෂර 1 ක් හෝ ඊට වැඩි ගණනකින් නිරූපණය කළ හැකි බැවින් ඔබ කේතන ක්‍රමය සැලකිල්ලට ගත යුතුය ක් බයිට් ක් ගණනක් (6 ක් පමණ) , විවිධ කේතීකරණ මඟින් මෙම බයිට් වලට වෙනස් ආකාරයකින් සලකනු ඇත.

ජොයෙල්ට මේ පිළිබඳව පළ කිරීමක් තිබේ:

නිරපේක්ෂ අවම සෑම මෘදුකාංග සංවර්ධකයෙක්ම යුනිකෝඩ් සහ අක්ෂර කට්ටල ගැන නිසැකවම දැන සිටිය යුතුය (නිදහසට කරුණක් නැත!)


6
"අක්ෂර 1 ක් බයිට් 1 ක් හෝ වැඩි ගණනකින් නිරූපණය කළ හැකිය" මම එකඟ වෙමි. මට අවශ්‍ය වන්නේ එම බයිට් කුමන කේතනයද යන්න නොසලකා. මතකයේ ගබඩා කළ හැකි එකම ක්‍රමය බයිට් වලින් පමණි. අක්ෂර පවා බයිට් 1 ක් හෝ වැඩි ගණනක් ගබඩා කර ඇත. මට අවශ්‍ය වන්නේ බයිට් වලට අත තැබීමයි.
ඇග්නෙල් කුරියන්

16
ඔබ (හෝ වෙනත් අයෙකු) සත්‍ය වශයෙන්ම දත්ත අර්ථ නිරූපණය කිරීමට අදහස් කරන්නේ නම් මිස , එය සාමාන්‍ය “බයිට් වාරණයක්” ලෙස නොසලකයි. සම්පීඩනය, ගුප්තකේතනය වැනි දේ සඳහා, කේතනය කිරීම ගැන කරදර වීම අර්ථ විරහිත ය. කේතන ක්‍රමය ගැන කරදර නොවී මෙය කළ හැකි ක්‍රමයක් සඳහා මගේ පිළිතුර බලන්න .
user541686

9
E මෙහර්දාඩ් - සම්පුර්ණයෙන්ම, නමුත් මුල් ප්‍රශ්නය, මා මුලින් පිළිතුරු දුන් විට, එම බයිට් පරිවර්තනය කළ පසු OP කුමක් සිදුවනු ඇත්දැයි සොයා බැලුවේ නැත, අනාගත සෙවුම් කරුවන්ට ඒ වටා ඇති තොරතුරු අදාළ වේ - මෙය ජොයෙල්ගේ පිළිතුරෙන් ඉතා හොඳින් ආවරණය වී ඇති අතර - ඔබේ පිළිතුර තුළ ඔබ සඳහන් කරන පරිදි: .NET ලෝකය තුළ රැඳී සිටිමින්, සහ / සිට හැරවීමට ඔබේ ක්‍රම භාවිතා කළහොත්, ඔබ සතුටු වේ. ඔබ එයින් පිටතට ගිය විගස, කේතීකරණය වැදගත් වේ.
ෂාෆ් - බෙන් ඩුගුයිඩ්

එක් කේත ලක්ෂ්‍යයක් බයිට් 4 ක් දක්වා නිරූපණය කළ හැකිය . (එක් යූටීඑෆ් -32 කේත ඒකකයක්, යූටීඑෆ් -16 ආදේශක යුගලයක් හෝ යූටීඑෆ් -8 බයිට් 4 ක් අවශ්‍ය වේ.) යූටීඑෆ් -8 සඳහා බයිට් 4 කට වඩා අවශ්‍ය අගයන් යුනිකෝඩ් 0x0..0x10FFFF පරාසයෙන් පිටත වේ. ;-)
DevSolar

89

මෙය ජනප්‍රිය ප්‍රශ්නයකි. ප්‍රශ්න කතුවරයා අසන දේ තේරුම් ගැනීම වැදගත් වන අතර එය වඩාත් පොදු අවශ්‍යතාවයට වඩා වෙනස් ය. අවශ්‍ය නොවන කේතය අනිසි ලෙස භාවිතා කිරීම අධෛර්යමත් කිරීම සඳහා, මම පසුව පිළිතුරු දුන්නෙමි.

පොදු අවශ්‍යතාවය

සෑම නූලකටම අක්ෂර කට්ටලයක් සහ කේතන ක්‍රමයක් ඇත. ඔබ System.Stringවස්තුවක් අරාවකට පරිවර්තනය කරන විට System.Byteතවමත් අක්ෂර කට්ටලයක් සහ කේතීකරණයක් ඇත. බොහෝ භාවිතයන් සඳහා, ඔබට අවශ්‍ය කුමන අක්ෂර කට්ටලය සහ කේතීකරණය ඔබ දන්නා අතර .NET "පරිවර්තනය සමඟ පිටපත් කිරීම" සරල කරයි. සුදුසු Encodingපන්තිය තෝරන්න .

// using System.Text;
Encoding.UTF8.GetBytes(".NET String to byte array")

ඉලක්කගත අක්‍ෂර කට්ටලය හෝ කේතීකරණය ප්‍රභවයේ ඇති අක්‍ෂරයකට සහය නොදක්වන අවස්ථා හැසිරවීමට පරිවර්තනයට අවශ්‍ය විය හැකිය. ඔබට තේරීම් කිහිපයක් තිබේ: ව්‍යතිරේකය, ආදේශ කිරීම හෝ මඟ හැරීම. පෙරනිමි ප්‍රතිපත්තිය වන්නේ '?' ආදේශ කිරීමයි.

// using System.Text;
var text = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes("You win €100")); 
                                                      // -> "You win ?100"

පැහැදිලිවම, පරිවර්තනයන් අනිවාර්යයෙන්ම පාඩු රහිත නොවේ!

සටහන: System.Stringප්‍රභව අක්ෂර කට්ටලය යුනිකෝඩ් වේ.

එකම අවුල් සහගත කාරණය නම් .NET එම අක්ෂර කට්ටලයේ එක් විශේෂිත කේතීකරණයේ නම සඳහා අක්ෂර කට්ටලයක නම භාවිතා කිරීමයි. Encoding.Unicodeකැඳවිය යුතුයි Encoding.UTF16.

බොහෝ භාවිතයන් සඳහා එය එයයි. ඔබට අවශ්‍ය වන්නේ එය නම්, මෙහි කියවීම නවත්වන්න. කේතීකරණයක් යනු කුමක්දැයි ඔබට වැටහෙන්නේ නැත්නම් විනෝදජනක ජොයෙල් ස්පොල්ස්කි ලිපිය බලන්න .

විශේෂිත අවශ්‍යතාවය

දැන්, ප්‍රශ්න කතුවරයා අසයි, "සෑම නූලක්ම බයිට් සමූහයක් ලෙස ගබඩා කර ඇත, හරිද? මට එම බයිට් තිබිය නොහැක්කේ ඇයි?"

ඔහුට කිසිම පරිවර්තනයක් අවශ්‍ය නැත.

සිට C # පිරිවිතර :

C # හි අක්ෂර සහ නූල් සැකසුම් යුනිකෝඩ් කේතීකරණ භාවිතා කරයි. වර්‍ග වර්ගය UTF-16 කේත ඒකකයක් නියෝජනය කරන අතර නූල් වර්ගය UTF-16 කේත ඒකක අනුක්‍රමයක් නියෝජනය කරයි.

ඉතින්, අපි දන්නවා අපි ශුන්‍ය පරිවර්තනයක් ඉල්ලා සිටියහොත් (එනම්, UTF-16 සිට UTF-16 දක්වා), අපට අපේක්ෂිත ප්‍රති result ලය ලැබෙනු ඇත:

Encoding.Unicode.GetBytes(".NET String to byte array")

නමුත් කේතන ක්‍රම සඳහන් නොකිරීමට නම් අප එය වෙනත් ආකාරයකින් කළ යුතුය. අතරමැදි දත්ත වර්ගයක් පිළිගත හැකි නම්, මේ සඳහා සංකල්පීය කෙටිමඟක් ඇත:

".NET String to byte array".ToCharArray()

එමඟින් අපට අපේක්ෂිත දත්ත සමුදාය නොලැබෙන නමුත් මෙහර්දාඩ්ගේ පිළිතුරෙන් පෙන්නුම් කරන්නේ මෙම චාර් අරා බ්ලොක්කොපි භාවිතයෙන් බයිට් අරා බවට පරිවර්තනය කරන්නේ කෙසේද යන්නයි . කෙසේ වෙතත්, මෙය නූල දෙවරක් පිටපත් කරයි! තවද, එය පැහැදිලිවම කේතීකරණ-විශේෂිත කේත භාවිතා කරයි: දත්ත සමුදාය System.Char.

නූල් ගබඩා කර ඇති සත්‍ය බයිට් වෙත ළඟා වීමට ඇති එකම ක්‍රමය වන්නේ දර්ශකයක් භාවිතා කිරීමයි. මෙම fixedප්රකාශය වටිනාකම් ලිපිනය ගනිමින් හැක. C # පිරිවිතරයෙන්:

[සඳහා] වර්ගයේ වචන ප්‍රකාශනයක් සඳහා, ... ආරම්භකය විසින් පළමු අක්‍ෂරයේ ලිපිනය ගණනය කරයි.

එසේ කිරීම සඳහා, සම්පාදකයා විසින් නූල් වස්තුවෙහි අනෙක් කොටස් සමඟ කේත මඟ හැරීම ලියයි RuntimeHelpers.OffsetToStringData. එබැවින්, අමු බයිට් ලබා ගැනීම සඳහා, නූලට දර්ශකයක් සාදා අවශ්‍ය බයිට් ගණන පිටපත් කරන්න.

// using System.Runtime.InteropServices
unsafe byte[] GetRawBytes(String s)
{
    if (s == null) return null;
    var codeunitCount = s.Length;
    /* We know that String is a sequence of UTF-16 codeunits 
       and such codeunits are 2 bytes */
    var byteCount = codeunitCount * 2; 
    var bytes = new byte[byteCount];
    fixed(void* pRaw = s)
    {
        Marshal.Copy((IntPtr)pRaw, bytes, 0, byteCount);
    }
    return bytes;
}

OdesCodesInChaos පෙන්වා දුන් පරිදි, ප්‍රති result ලය රඳා පවතින්නේ යන්ත්‍රයේ අවසානය මත ය. නමුත් ප්‍රශ්න කතුවරයා ඒ ගැන තැකීමක් නොකරයි.


3
An යාන් එය නිවැරදියි නමුත් නූල් දිග දැනටමත් කේත-ඒකක ගණන ලබා දෙයි (කේත ලක්ෂ්‍ය නොවේ).
ටොම් බ්ලොජට්

1
එය පෙන්වා දීමට ස්තූතියි! එම්එස්ඩීඑන් වෙතින්: " Lengthදේපල [හි String] Charමෙම අවස්ථාවෙහි ඇති වස්තු ගණන ආපසු ලබා දෙයි, යුනිකෝඩ් අක්ෂර ගණන නොවේ." එබැවින් ඔබගේ උදාහරණ කේතය ලියා ඇති පරිදි නිවැරදි ය.
ජෑන් හෙට්ටිච්

1
upsupercat "වර්‍ග වර්ගය යූටීඑෆ් -16 කේත ඒකකයක් නියෝජනය කරයි, සහ නූල් වර්ගය යූටීඑෆ් -16 කේත ඒකක අනුක්‍රමයක් නියෝජනය කරයි." C_ සී # 5 පිරිවිතර ._ ඔව්, අවලංගු යුනිකෝඩ් නූලක් වළක්වන කිසිවක් නැත:new String(new []{'\uD800', '\u0030'})
ටොම් බ්ලොජට්

1
@TomBlodget: සිත් එක් අවස්ථා ගනී නම් Globalization.SortKey, කුංකුම KeyData, සහ ඇසුරුම් එක් එක් එහි ප්රතිඵලයක් බයිට් බවට String[අනුව චරිතය බයිට් දෙකක්, පළමු MSB ], ඉල්ලා String.CompareOrdinalඵලිත නූල් නොදැරූ වඩා සැලකිය යුතු වේගයකින් වනු ඇත SortKey.Compareඅවස්ථාවන්හි මත SortKey, හෝ memcmpඑම අවස්ථාවන් ඉල්ලා සිටීම පවා . ඒ අනුව, මම කල්පනා කරන්නේ, KeyDataByte[]වෙනුවට ආපසු Stringඑන්නේ ඇයි?
සුපර් කැට්

1
අහෝ, නිවැරදි පිළිතුර, නමුත් වසර ප්‍රමාද වැඩියි, පිළිගත් තරම් ඡන්ද කවදාවත් නොලැබේ. ටීඑල් නිසා ඩීආර් ජනතාව පිළිගත් පිළිතුරු පාෂාණ යැයි සිතනු ඇත. copyenpastit සහ ඉහළට ඡන්දය දෙන්න.
මාටින් කපොඩිසි

46

ඔබගේ ප්‍රශ්නයේ පළමු කොටසට (බයිට් ලබා ගන්නේ කෙසේද) දැනටමත් වෙනත් අය පිළිතුරු දී ඇත: බලන්න System.Text.Encoding නාම අවකාශය .

ඔබගේ පසු විපරම් ප්‍රශ්නය මම අමතන්නෙමි: ඔබට කේතීකරණයක් තෝරා ගැනීමට අවශ්‍ය ඇයි? ඔබට එය පන්ති පන්තියෙන්ම ලබා ගත නොහැක්කේ ඇයි?

පිළිතුර කොටස් දෙකකින් යුක්තය.

පළමුවෙන්ම, නූල් පන්තිය විසින් අභ්‍යන්තරව භාවිතා කරන බයිට් වැදගත් නොවේ , ඔබ ඒවා උපකල්පනය කරන සෑම විටම ඔබ දෝෂයක් හඳුන්වා දෙයි.

ඔබේ වැඩසටහන මුළුමනින්ම .Net ලෝකය තුළ තිබේ නම්, ඔබ ජාලයක් හරහා දත්ත යවුවද, නූල් සඳහා බයිට් අරා ලබා ගැනීම ගැන කරදර විය යුතු නැත. ඒ වෙනුවට, දත්ත සම්ප්‍රේෂණය කිරීම ගැන කරදර වීමට .Net Serialization භාවිතා කරන්න. සත්‍ය බයිට් ගැන ඔබ තවදුරටත් කරදර නොවන්න: අනුක්‍රමිකකරණ ආකෘතිය එය ඔබ වෙනුවෙන් කරයි.

අනෙක් අතට, ඔබ සහතික කළ නොහැකි තැනකට මෙම බයිට් යවන්නේ නම් .නෙට් අනුක්‍රමික ප්‍රවාහයකින් දත්ත ලබා ගනීද? මෙම අවස්ථාවේ දී ඔබ අනිවාර්යයෙන්ම කේතීකරණය ගැන කරදර විය යුතුය, මන්ද පැහැදිලිවම මෙම බාහිර පද්ධතිය සැලකිලිමත් වේ. එබැවින් නැවතත්, නූල භාවිතා කරන අභ්‍යන්තර බයිට් වැදගත් නැත: ඔබට කේතන ක්‍රමයක් තෝරා ගැනීමට අවශ්‍ය වන අතර එමඟින් .Net විසින් අභ්‍යන්තරව භාවිතා කරන එකම කේතන ක්‍රමයක් වුවද ලැබීමේ කෙළවරේ මෙම කේතන ක්‍රමය පිළිබඳව ඔබට පැහැදිලි විය හැකිය.

මෙම අවස්ථාවෙහිදී, ඔබේ බයිට් ප්‍රවාහය නිර්මාණය කිරීමෙන් යම් වැඩක් ඉතිරි කර ගත හැකිය යන අදහසින්, හැකි සෑම අවස්ථාවකදීම මතක විචල්‍යය මගින් ගබඩා කර ඇති සත්‍ය බයිට් මතකයේ භාවිතා කිරීමට ඔබ කැමති බව මට වැටහේ. කෙසේ වෙතත්, මම ඔබට එය ඉදිරිපත් කළේ ඔබේ ප්‍රතිදානය අනෙක් අන්තයේ තේරුම් ගෙන ඇති බවට සහතික කර ගැනීම හා සසඳන විට එය වැදගත් නොවන අතර ඔබේ කේතීකරණය සමඟ ඔබ පැහැදිලිව සිටිය යුතු බවට සහතික වීමෙනි. මීට අමතරව, ඔබට ඇත්ත වශයෙන්ම ඔබේ අභ්‍යන්තර බයිට් ගැලපීමට අවශ්‍ය නම්, ඔබට දැනටමත් තෝරා ගත හැකියUnicode කේතන ක්‍රමය එම කාර්ය සාධන ඉතිරිකිරීම් ලබා ගත හැකිය.

වන දෙවන කොටස මට ඒ මහතාට කීමට ... මෙම තෝරා Unicodeකේතන ඇත කියන්නේ .නෙට් බයිට් භාවිතා කිරීමට. ඔබට මෙම කේතන ක්‍රමය තෝරා ගැනීමට අවශ්‍යය, මන්ද යත් සමහර නව-විකාර යුනිකෝඩ්-ප්ලස් එළියට එන විට .නෙට් ධාවන කාලයට ඔබේ වැඩසටහන කඩ නොකර මෙම නව, වඩා හොඳ කේතීකරණ ආකෘතිය භාවිතා කිරීමට නිදහස තිබිය යුතුය. නමුත්, මේ මොහොතේ (සහ අනාගතය සඳහා), යුනිකෝඩ් කේතන ක්‍රමය තෝරා ගැනීමෙන් ඔබට අවශ්‍ය දේ ලැබේ.

ඔබේ නූල වයර් වෙත නැවත ලිවිය යුතු බව වටහා ගැනීම ද වැදගත් වන අතර, ඔබ ගැලපෙන කේතීකරණයක් භාවිතා කරන විට පවා අවම වශයෙන් බිට්-රටාවේ යම් පරිවර්තනයක් සිදු වේ . බිග් එදිරිව ලිට්ල් එන්ඩියන්, ජාල බයිට් ඇණවුම, පැකට්කරණය, සැසි තොරතුරු යනාදිය සඳහා පරිගණකයට ගණනය කළ යුතුය.


9
.NET හි ඔබට නූල් සඳහා බයිට් අරා ලබා ගත යුතු ප්‍රදේශ තිබේ. .NET ගුප්ත ලේඛන පංති බොහොමයක බයිට් අරා හෝ ප්‍රවාහය පිළිගන්නා ComputeHash () වැනි ක්‍රම අඩංගු වේ. පළමුවෙන්ම බයිට් අරාවකට පරිවර්තනය කිරීම (එන්කෝඩින් එකක් තෝරා ගැනීම) හැර විකල්පයක් ලෙස එය ප්‍රවාහයක ඔතා තැබීම හැර ඔබට වෙනත් විකල්පයක් නොමැත. කෙසේ වෙතත් ඔබ කේතන ක්‍රමයක් (එනම් යූටීඑෆ් 8) තෝරා ගන්නා තාක් කල් මේ සමඟ කිසිදු ගැටළුවක් නොමැත.
අළු

44

යන්තම් Mehrdrad ශබ්ද බව පැහැදිලි කිරීමට පිළිතුරු ඔහුගේ ප්රවේශය පවා අඛන්ඩව පැවතිය හැකි, එය ක්රියා යුගලනය නොවූ අන්වාදේශ චරිත බොහෝ මගේ පිළිතුර එරෙහිව එල්ල වූ වන (නමුත්, සෑම කෙනෙකුටම එක හා සමානව වරදකරු වන,, උදා: System.Text.Encoding.UTF8.GetBytes, System.Text.Encoding.Unicode.GetBytesඑම සංකේතවත් ක්රම ඉහළ අන්වාදේශ දිගටම නොහැක; d800උදාහරණයක් ලෙස අක්ෂර , සහ ඒවා හුදෙක් ඉහළ ආදේශක අක්‍ෂර අගය වෙනුවට ආදේශ කරයි fffd):

using System;

class Program
{     
    static void Main(string[] args)
    {
        string t = "爱虫";            
        string s = "Test\ud800Test"; 

        byte[] dumpToBytes = GetBytes(s);
        string getItBack = GetString(dumpToBytes);

        foreach (char item in getItBack)
        {
            Console.WriteLine("{0} {1}", item, ((ushort)item).ToString("x"));
        }    
    }

    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);
    }        
}

ප්‍රතිදානය:

T 54
e 65
s 73
t 74
? d800
T 54
e 65
s 73
t 74

System.Text.Encoding.UTF8.GetBytes හෝ System.Text.Encoding.Unicode.GetBytes සමඟ එය උත්සාහ කරන්න , ඒවා හුදෙක් ඉහළ ආදේශක අක්ෂර වෙනුවට වටිනාකමක් ලබා දෙනු ඇත fffd

මෙම ප්‍රශ්නයේ චලනයක් ඇති සෑම අවස්ථාවකම, මම තවමත් සිතන්නේ අනුක්‍රමික යන්ත්‍රයක් (එය මයික්‍රොසොෆ්ට් හෝ තෙවන පාර්ශවීය සංරචක වේවා) නූල් නොනැසී පැවතිය හැකි අතර එහි නොගැලපෙන අන්‍යාගමික අක්ෂර අඩංගු වේ; මම මෙය සෑම විටම ගූගල් කරමි: අනුක්‍රමිකකරණය නොකල අන්‍යාගමික චරිතය .NET . මෙය මට කිසිදු නින්දක් නැති කර නොගනී, නමුත් සෑම විටම මගේ පිළිතුරෙහි යම් දෝෂයක් ඇති බව කවුරුහරි අදහස් දක්වන විට එය යම් ආකාරයක කරදරයක් වන නමුත්, නොගැලපෙන අන්‍යාගමික චරිත සම්බන්ධයෙන් ඔවුන්ගේ පිළිතුරු සමානවම දෝෂ සහිතය.

හෙන ගහපන්, මයික්රොසොෆ්ට් පමණක් භාවිතා කළ යුතු System.Buffer.BlockCopyඑහි BinaryFormatter

谢谢


3
වලංගු කේත ලකුණු සෑදීම සඳහා අන්‍යාගමිකයින් යුගල වශයෙන් පෙනී සිටිය යුතු නොවේද? එය එසේ නම්, දත්ත හැසිරවිය හැක්කේ මන්දැයි මට තේරුම් ගත හැකිය.
dtanders

1
ඔව්, එය මගේ සිතුවිලි ද වේ, ඒවා යුගල වශයෙන් පෙනී සිටිය යුතුය, යුගල නොකළ අන්‍යාගමික චරිත සිදුවන්නේ ඔබ හිතාමතාම ඒවා නූල් මත තබා ඒවා යුගලනය නොකළහොත් පමණි. මා නොදන්නා දෙය නම්, අනුක්‍රමිකකරණ ප්‍රවේශය ( අවුරුදු 3 කට වඩා වැඩි කාලයක් තිස්සේ පිළිගත් පිළිතුරක් වූ මගේ පිළිතුර) අනුක්‍රමිකකරණ ප්‍රවේශය ලෙස සැලකූ විට, ඒ වෙනුවට අපි කේතීකරණ දැනුවත් ප්‍රවේශයක් භාවිතා කළ යුතු යැයි වෙනත් දේවාලයන් දිගින් දිගටම හිරිහැර කරන්නේ ඇයි? අන්වාදේශ චරිතය නොවෙනස්ව පවතී. එහෙත්, ඔව්හු තමන්ගේ කේතන-දැනුවත් විසඳුම්, පුදුමයට ද යුගලනය නොවූ අන්වාදේශ චරිතය තබා නැතツබව පරීක්ෂා කිරීමට අමතක
මයිකල් Buen

System.Buffer.BlockCopyඅභ්‍යන්තරව භාවිතා කරන අනුක්‍රමිකකරණ පුස්තකාලයක් තිබේ නම් , සියලු කේතීකරණ-උපදේශක පුද්ගලයින්ගේ තර්ක විතර්ක වනු ඇත
මයිකල් බුවෙන්

2
Ic මයිකල්බූන් මට පෙනෙන පරිදි ප්‍රධාන කාරණය වන්නේ ඔබ විශාල අකුරු සහිත අකුරුවලින් යමක් කීම වැදගත් නොවන බව පවසමින් ඔවුන්ගේ කාරණයේදී එය වැදගත් නොවන බව පැවසීමයි. එහි ප්‍රති As ලයක් වශයෙන්, ඔබේ පිළිතුර දෙස බලන පුද්ගලයින්ට මූලික ක්‍රමලේඛන වැරදි කිරීමට දිරිගන්වන අතර එමඟින් අනාගතයේදී අන් අය කලකිරීමට පත් වේ. නොගෙවූ අන්‍යාගමිකයන් නූලක වලංගු නොවේ. එය වර්‍ග අරාව නොවේ, එබැවින් නූලක් වෙනත් ආකෘතියකට පරිවර්තනය FFFDකිරීමෙන් එම චරිතයේ දෝෂයක් ඇතිවිය හැකි බව හැඟේ. ඔබට අතින් නූල් හැසිරවීම කිරීමට අවශ්‍ය නම්, නිර්දේශිත පරිදි වර්‍ගයක් භාවිතා කරන්න.
Trisped

2
tdtanders: A System.Stringයනු වෙනස් කළ නොහැකි අනුක්‍රමයකි Char; .නෙට් සෑම විටම ඕනෑම Stringදෙයකින් වස්තුවක් තැනීමට ඉඩ දී Char[]එහි අන්තර්ගතය Char[]එකම අගයන් සහිත අපනයනය කරයි , මුල් Char[]පිටුවේ යුගල නොකළ ආදේශක තිබුණත් .
සුපර් කැට්

41

මෙය අඩු කේතයක් උත්සාහ කරන්න:

System.Text.Encoding.UTF8.GetBytes("TEST String");

ඉන්පසු මෙය උත්සාහ System.Text.Encoding.UTF8.GetBytes("Árvíztűrő tükörfúrógép);කර අ cry න්න! එය ක්‍රියාත්මක වනු ඇත, නමුත් System.Text.Encoding.UTF8.GetBytes("Árvíztűrő tükörfúrógép").Length != System.Text.Encoding.UTF8.GetBytes("Arvizturo tukorfurogep").Lengthඅතර"Árvíztűrő tükörfúrógép".Length == "Arvizturo tukorfurogep".Length
mg30rg

9
@ mg30rg: ඔබේ ආදර්ශය අමුතු යැයි ඔබ සිතන්නේ ඇයි? නිසැකවම විචල්ය-පළල කේතන ක්‍රමයක් තුළ සෑම අක්ෂරයකම එකම බයිට් දිගක් නොමැත. එහි ඇති වරද කුමක්ද?
ව්ලැඩ්

La ව්ලැඩ් මෙහි වඩා වලංගු අදහස් දැක්වීමක් නම්, සංකේතවත් කරන ලද යුනිකෝඩ් සංකේත ලෙස (බයිට් ලෙස), ඔවුන්ගේම ඩයක්‍රිටික්ස් ඇතුළත් වන අක්ෂර, අක්ෂරයට එකතු කරන ලද විකරණකාරක සංකේතවලට බෙදී ඇති ඩයක්‍රිටික් වලට වඩා වෙනස් ප්‍රති result ලයක් ලබා දෙනු ඇත . නමුත් නියත බයිට් නිරූපණයක් ලබා ගැනීමට ඉඩ දීම සඳහා ඒවා වෙන් කිරීම සඳහා .net හි ක්‍රම තිබේ.
නයර්ගුඩ්ස්

25

හොඳයි, මම සියලු පිළිතුරු කියවා ඇති අතර ඒවා කේතනය කිරීම හෝ යුගලනය නොකළ අන්‍යාගමිකයන් පහත වැටෙන අනුක්‍රමිකකරණය ගැන එකක් විය.

නිදසුනක් ලෙස, නූල බයිට් අරා ගබඩාවකින් සාදන ලද SQL සේවාදායකයෙන් එන විට එය නරක ය, උදාහරණයක් ලෙස මුරපද හැෂ්. අපි එයින් යමක් අතහැර දැමුවහොත්, එය අවලංගු හැෂ් එකක් ගබඩා කරනු ඇති අතර, අපට එය එක්ස්එම්එල් හි ගබඩා කිරීමට අවශ්‍ය නම්, අපට එය එලෙසම තැබීමට අවශ්‍යය (මක්නිසාද යත්, එක්ස්එම්එල් ලේඛකයා විසින් සොයා ගන්නා ලද නොගැලපෙන අන්‍යාගමිකයෙකු සඳහා ව්‍යතිරේකයක් අතහැර දමයි).

එබැවින් මම එවැනි අවස්ථාවන්හිදී බයිට් අරා වල Base64 කේතන ක්‍රමයක් භාවිතා කරමි , නමුත් හේයි, අන්තර්ජාලයේ C # හි මේ සඳහා ඇත්තේ එකම විසඳුමකි, එය එහි දෝෂයක් ඇති අතර එය එක් ක්‍රමයක් පමණි, එබැවින් මම දෝෂය නිවැරදි කර නැවත ලියා ඇත පටිපාටිය. මෙන්න ඔබ, අනාගත ගූගල්කරුවන්:

public static byte[] StringToBytes(string str)
{
    byte[] data = new byte[str.Length * 2];
    for (int i = 0; i < str.Length; ++i)
    {
        char ch = str[i];
        data[i * 2] = (byte)(ch & 0xFF);
        data[i * 2 + 1] = (byte)((ch & 0xFF00) >> 8);
    }

    return data;
}

public static string StringFromBytes(byte[] arr)
{
    char[] ch = new char[arr.Length / 2];
    for (int i = 0; i < ch.Length; ++i)
    {
        ch[i] = (char)((int)arr[i * 2] + (((int)arr[i * 2 + 1]) << 8));
    }
    return new String(ch);
}

බයිට් අරා බේස් 64 බවට පරිවර්තනය කිරීම සඳහා ඔබේ අභිරුචි ක්‍රමය භාවිතා කරනවා වෙනුවට, ඔබ කළ යුතුව තිබුණේ බිල්ට් පරිවර්තකය භාවිතා කිරීම පමණි: Convert.ToBase64String (arr);
මාකෝටෝසන්

Ak මාකෝටෝසන් ස්තූතියි, නමුත් මම පදනම් Convert.ToBase64String(arr); 64 පරිවර්තනය සඳහා භාවිතා කළෙමි byte[] (data) <-> string (serialized data to store in XML file). නමුත් ආරම්භක ලබා ගැනීම සඳහා ද්විමය දත්ත අඩංගු byte[] (data)යමක් කිරීමට මට අවශ්‍ය විය (එය MSSQL විසින් එය මට ආපසු ලබා දුන් ආකාරයයි). SO ඉහත කාර්යයන් සඳහා වේ. StringString (binary data) <-> byte[] (easy accessible binary data)
Gman

23

කේතන ක්‍රමය සැලකිල්ලට ගත යුත්තේ මන්දැයි කරුණාකර පැහැදිලි කරන්න. නූල් ගබඩා කර ඇති බයිට් මොනවාදැයි මට සරලව ලබා ගත නොහැකිද? මෙම කේතන ක්‍රමය මත යැපෙන්නේ ඇයි? !!!

මන්ද යත් “නූල් වල බයිට්” වැනි දෙයක් නොමැති බැවිනි.

නූලක් (හෝ වඩාත් සාමාන්‍යයෙන්, පෙළක්) අක්ෂර වලින් සමන්විත වේ: අකුරු, ඉලක්කම් සහ වෙනත් සංකේත. එච්චරයි. පරිගණක, කෙසේ වෙතත්, චරිත ගැන කිසිවක් දන්නේ නැත; ඔවුන්ට හැසිරවිය හැක්කේ බයිට් පමණි. එමනිසා, ඔබට පරිගණකයක් භාවිතා කර පෙළ ගබඩා කිරීමට හෝ සම්ප්‍රේෂණය කිරීමට අවශ්‍ය නම්, ඔබට අක්ෂර බයිට් බවට පරිවර්තනය කළ යුතුය. ඔබ එය කරන්නේ කෙසේද? මෙන්න කේතීකරණ ස්ථානයට පැමිණේ.

කේතන ක්‍රමයක් යනු තාර්කික අක්ෂර භෞතික බයිට් වලට පරිවර්තනය කිරීමේ සම්මුතියකි. සරලම හා වඩාත්ම දන්නා කේතන ක්‍රමය ASCII වන අතර ඔබ ඉංග්‍රීසියෙන් ලියන්නේ නම් ඔබට අවශ්‍ය වන්නේ එයයි. වෙනත් භාෂාවන් සඳහා ඔබට වඩාත් සම්පූර්ණ කේතීකරණ අවශ්‍ය වනු ඇත, ඕනෑම යුනිකෝඩ් රසයක් වර්තමානයේ ආරක්ෂිතම තේරීම වේ.

කෙටියෙන් කිවහොත්, “කේතීකරණ භාවිතා නොකර නූලක බයිට් ලබා ගැනීමට” උත්සාහ කිරීම “කිසිදු භාෂාවක් භාවිතා නොකර පෙළක් ලිවීම” තරම්ම කළ නොහැකි ය.

මාර්ගය වන විට, මෙම කුඩා ප්‍ර wisdom ාව කියවීමට මම ඔබට (සහ ඕනෑම කෙනෙකුට) තරයේ නිර්දේශ කරමි: නිරපේක්ෂ අවම සෑම මෘදුකාංග සංවර්ධකයෙක්ම නියත වශයෙන්ම, යුනිකෝඩ් සහ චරිත කට්ටල ගැන ධනාත්මකව දැන සිටිය යුතුය (නිදහසට කරුණක් නැත!)


2
පැහැදිලි කිරීමට මට ඉඩ දෙන්න: "හෙලෝ වර්ල්ඩ්" භෞතික බයිට් වලට පරිවර්තනය කිරීම සඳහා කේතන ක්‍රමයක් භාවිතා කර ඇත. නූල මගේ පරිගණකයේ ගබඩා කර ඇති බැවින් එය බයිට් වල ගබඩා කළ යුතු බව මට විශ්වාසයි. මට අවශ්‍ය වන්නේ එම බයිට් තැටියේ හෝ වෙනත් හේතුවක් නිසා සුරැකීමට ප්‍රවේශ වීමයි. මෙම බයිට් අර්ථ නිරූපණය කිරීමට මට අවශ්‍ය නැත. මෙම බයිට් අර්ථ නිරූපණය කිරීමට මට අවශ්‍ය නැති නිසා, මේ අවස්ථාවේ දී කේතීකරණයේ අවශ්‍යතාවය අස්ථානගත වී ඇත්තේ printf ඇමතීමට දුරකථන මාර්ගයක් අවශ්‍ය වීමෙනි.
ඇග්නෙල් කුරියන්

3
නමුත් නැවතත්, ඔබ කේතීකරණයක් භාවිතා නොකරන්නේ නම් පෙළ-භෞතික-බයිට්-පරිවර්තනය පිළිබඳ සංකල්පයක් නොමැත. නිසැකවම, සම්පාදකයා නූල් කෙසේ හෝ මතකයේ ගබඩා කරයි - නමුත් එය භාවිතා කරන්නේ ඔබ (හෝ සම්පාදක සංවර්ධකයා හැර වෙනත් කිසිවෙකු) නොදන්නා අභ්‍යන්තර කේතීකරණයක් පමණි. එබැවින්, ඔබ කුමක් කළත්, නූලකින් භෞතික බයිට් ලබා ගැනීමට ඔබට කේතීකරණයක් අවශ්‍ය වේ.
කොනාමිමන්

@ ඇග්නෙල් කුරියන්: ඇත්ත වශයෙන්ම සත්‍යයකි, නූලක එහි අන්තර්ගතය ගබඩා කරන බයිට් පොකුරක් කොතැනක හෝ ඇති බව (යූටීඑෆ් -16 දුරින්). නමුත් ඔබට එයට ප්‍රවේශ වීම වැළැක්වීමට හොඳ හේතුවක් තිබේ: නූල් වෙනස් නොවන අතර ඔබට අභ්‍යන්තර බයිට් [] අරාව ලබා ගත හැකි නම්, ඔබට එයද වෙනස් කළ හැකිය. මෙය වෙනස් කළ නොහැකි බව බිඳ දමයි, මන්දයත් බහු නූල් එකම දත්ත බෙදා ගත හැකි බැවිනි. නූල ලබා ගැනීම සඳහා යූටීඑෆ් -16 කේතීකරණයක් භාවිතා කිරීමෙන් දත්ත පිටපත් වනු ඇත.
ollb

2
N ගනාෆූ, බයිට් වල පිටපතක් කරනු ඇත.
ඇග්නෙල් කුරියන්

22

A # අරාවකට පරිවර්තනය stringකිරීමට byte:

public static byte[] StrToByteArray(string str)
{
   System.Text.UTF8Encoding  encoding=new System.Text.UTF8Encoding();
   return encoding.GetBytes(str);
}

17
byte[] strToByteArray(string str)
{
    System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
    return enc.GetBytes(str);
}

නමුත්, කේතන ක්‍රමය සැලකිල්ලට ගත යුත්තේ ඇයි? භාවිතා කරන්නේ කුමන කේතන ක්‍රමයක් දැයි නොදැන මට බයිට් ලබා ගත නොහැක්කේ ඇයි? එය අවශ්‍ය වුවද, භාවිතා කරන කේතන ක්‍රමය කුමක්දැයි සංගීත වස්තුව විසින්ම දැනගෙන මතකයේ ඇති දේ ඉවත දැමිය යුතු නොවේද?
ඇග්නෙල් කුරියන්

5
මෙය සැමවිටම ක්‍රියාත්මක නොවේ. සමහර විශේෂ චරිත එවැනි ක්‍රමයක් භාවිතා කිරීමෙන් මග හැරී යා හැකිය.
ජේබී කිං

17

නූල් සහ බයිට් අරාව අතර පරිවර්තනය සඳහා ඔබට පහත කේතය භාවිතා කළ හැකිය.

string s = "Hello World";

// String to Byte[]

byte[] byte1 = System.Text.Encoding.Default.GetBytes(s);

// OR

byte[] byte2 = System.Text.ASCIIEncoding.Default.GetBytes(s);

// Byte[] to string

string str = System.Text.Encoding.UTF8.GetString(byte1);

VUPthis මගේ ගැටලුව විසඳීය (බයිට් [] ff = ASCIIEncoding.ASCII.GetBytes (barcodetxt.Text);)
r.hamd

16

Span<T>සී # 7.2 සමඟ මුදා හැරීමත් සමඟ, කළමනාකරණය කරන ලද බයිට් අරාවකට නූල් වල යටින් පවතින මතක නිරූපණය ග්‍රහණය කර ගැනීමේ කැනොනිකල් තාක්‍ෂණය:

byte[] bytes = "rubbish_\u9999_string".AsSpan().AsBytes().ToArray();

එය නැවත පරිවර්තනය කිරීම ආරම්භකයකු නොවිය යුතුය, මන්ද එයින් අදහස් වන්නේ ඔබ ඇත්ත වශයෙන්ම දත්ත කෙසේ හෝ අර්ථ නිරූපණය කරන නමුත් සම්පූර්ණත්වය උදෙසා ය:

string s;
unsafe
{
    fixed (char* f = &bytes.AsSpan().NonPortableCast<byte, char>().DangerousGetPinnableReference())
    {
        s = new string(f);
    }
}

නම් NonPortableCastසහ DangerousGetPinnableReferenceඔබ මෙය බොහෝ විට නොකළ යුතු බවට තර්කය තවදුරටත් ඉදිරිපත් කළ යුතුය.

වැඩ Span<T>කිරීමට System.Memory NuGet පැකේජය ස්ථාපනය කිරීම අවශ්‍ය බව සලකන්න .

කෙසේ වෙතත්, සත්‍ය මුල් ප්‍රශ්නය සහ පසු විපරම් අදහස් වලින් ගම්‍ය වන්නේ යටින් පවතින මතකය “අර්ථ නිරූපණය” නොකිරීමයි (එයින් මා සිතන්නේ එය වෙනස් කිරීමක් හෝ එය ලිවීමේ අවශ්‍යතාවයෙන් ඔබ්බට කියවා නැති බවයි), එයින් පෙන්නුම් කරන්නේ Streamපන්තියේ යම් ක්‍රියාත්මක කිරීමක් දත්ත කිසිසේත්ම නූල් ලෙස තර්ක කිරීම වෙනුවට භාවිතා කළ යුතුය.


13

මට විශ්වාස නැත, නමුත් මම සිතන්නේ නූල එහි තොරතුරු අක්ෂර මාලාවක් ලෙස ගබඩා කරන අතර එය බයිට් සමඟ අකාර්යක්ෂම වේ. නිශ්චිතවම, වර්‍ගයක අර්ථ දැක්වීම "යුනිකෝඩ් අක්ෂරයක් නියෝජනය කරයි" යන්නයි.

මෙම උදාහරණ සාම්පලය ගන්න:

String str = "asdf éß";
String str2 = "asdf gh";
EncodingInfo[] info =  Encoding.GetEncodings();
foreach (EncodingInfo enc in info)
{
    System.Console.WriteLine(enc.Name + " - " 
      + enc.GetEncoding().GetByteCount(str)
      + enc.GetEncoding().GetByteCount(str2));
}

අවස්ථා දෙකේදීම යුනිකෝඩ් පිළිතුර බයිට් 14 ක් වන අතර යූටීඑෆ් -8 පිළිතුර පළමු සඳහා බයිට් 9 ක් පමණක් වන අතර දෙවැන්න සඳහා 7 ක් පමණි.

එබැවින් ඔබට නූල භාවිතා කරන බයිට් අවශ්‍ය නම් සරලව භාවිතා කරන්න Encoding.Unicode, නමුත් එය ගබඩා ඉඩ ප්‍රමාණය සමඟ අකාර්යක්ෂම වනු ඇත.


10

ප්‍රධාන ගැටළුව වන්නේ නූලක ඇති ග්ලයිෆෝනයකට බිටු 32 ක් (අක්ෂර කේතයක් සඳහා බිටු 16 ක්) ගත වන නමුත් බයිට් එකකට ඉතිරිව ඇත්තේ බිට් 8 ක් පමණි. ASCII අක්ෂර පමණක් අඩංගු වන නූල් වලට ඔබ සීමා නොවන්නේ නම්, එකින් එක සිතියම්කරණය නොපවතී. System.Text.Encoding ට බයිට් කිරීමට නූලක් සිතියම් ගත කිරීමට බොහෝ ක්‍රම තිබේ [], ඔබ තොරතුරු නැතිවීම වළක්වන එකක් තෝරා ගත යුතු අතර ඔබේ සේවාදායකයාට බයිට් සිතියම් ගත කිරීමට අවශ්‍ය වූ විට එය භාවිතා කිරීමට පහසු වේ. .

Utf8 යනු ජනප්‍රිය කේතීකරණයක් වන අතර එය සංයුක්ත වන අතර එය පාඩු නොවේ.


3
UTF-8 සංයුක්ත වන්නේ ඔබේ අක්ෂරවලින් බහුතරයක් ඉංග්‍රීසි (ASCII) අක්ෂර කට්ටලයේ තිබේ නම් පමණි. ඔබට දිගු චීන අක්ෂර මාලාවක් තිබේ නම්, යූටීඑෆ් -16 එම නූල සඳහා යූටීඑෆ් -8 ට වඩා සංයුක්ත කේතීකරණයක් වනු ඇත. මෙයට හේතුව යූටීඑෆ් -8 ASCII කේතනය කිරීම සඳහා එක් බයිට් එකක් භාවිතා කරන අතර 3 (හෝ සමහර විට 4) වෙනත් ආකාරයකින්.
ජොයෙල් මුලර්

7
සැබෑ. එහෙත්, ඔබ චීන පෙළ හැසිරවීමට හුරුපුරුදු නම් කේතීකරණය ගැන ඔබ නොදන්නේ කෙසේද?
හාන්ස් පැසන්ට්

9

භාවිත:

    string text = "string";
    byte[] array = System.Text.Encoding.UTF8.GetBytes(text);

ප්රති result ලය:

[0] = 115
[1] = 116
[2] = 114
[3] = 105
[4] = 110
[5] = 103

OP නිශ්චිතවම කේතීකරණයක් නියම නොකරන ලෙස ඉල්ලා සිටී ... "නිශ්චිත කේතීකරණයක් අතින් නියම නොකර"
ෆර්ඩ්ස්

8

වේගවත්ම ක්‍රමය

public static byte[] GetBytes(string text)
{
    return System.Text.ASCIIEncoding.UTF8.GetBytes(text);
}

මාකෝටොසන් අදහස් දැක්වූ පරිදි සංස්කරණය කරන්න මෙය දැන් හොඳම ක්‍රමයයි:

Encoding.UTF8.GetBytes(text)

8
ASCIIEncoding ..... අවශ්‍ය නොවේ. Encoding.UTF8.GetBytes (පෙළ) භාවිතා කිරීම වඩාත් සුදුසුය.
මාකෝටෝසන්

8

.

.NET හි ඇති නූලක් UTF-16 කේත ඒකක අනුක්‍රමයක් ලෙස පෙළ නිරූපණය කරයි, එබැවින් බයිට් දැනටමත් UTF-16 හි මතකයේ කේතනය කර ඇත.

මෙහර්දාඩ්ගේ පිළිතුර

ඔබට මෙහර්දාඩ්ගේ පිළිතුර භාවිතා කළ හැකිය , නමුත් එය ඇත්ත වශයෙන්ම කේතන ක්‍රමයක් භාවිතා කරයි, මන්ද අක්ෂර යූටීඑෆ් -16 වේ. එය ToCharArray ලෙස හඳුන්වන අතර එය ප්‍රභවය දෙස බැලීමෙන් a නිර්මාණය වන char[]අතර මතකය කෙලින්ම පිටපත් කරයි. ඉන්පසු එය දත්ත වෙන් කර ඇති බයිට් අරාවකට පිටපත් කරයි. එබැවින් කබාය යටතේ එය යටින් පවතින බයිට් දෙවරක් පිටපත් කර ඇමතුමෙන් පසුව භාවිතා නොකරන වර්‍ග අරාවක් වෙන් කරයි.

ටොම් බ්ලොජෙට්ගේ පිළිතුර

ටොම් බ්ලොජෙට්ගේ පිළිතුර මෙහර්දාඩ්ට වඩා 20-30% වේගවත් වන අතර එය වර්‍ග අරාවක් වෙන් කර බයිට් පිටපත් කිරීමේ අතරමැදි පියවර මඟ හරින බැවින් එය /unsafeවිකල්පය සමඟ සම්පාදනය කිරීම අවශ්‍ය වේ . ඔබට නියත වශයෙන්ම කේතීකරණ භාවිතා කිරීමට අවශ්‍ය නැතිනම්, මම සිතන්නේ මෙය යා යුතු මාර්ගයයි. ඔබ ඔබේ සංකේතාංකන පිවිසුම fixedබ්ලොක් එක තුළ තැබුවහොත් , ඔබට වෙනම බයිට් අරාවක් වෙන් කර එයට බයිට් පිටපත් කිරීමට පවා අවශ්‍ය නොවේ.

එසේම, කේතන කිරීම සැලකිල්ලට ගත යුත්තේ ඇයි? නූල් ගබඩා කර ඇති බයිට් මොනවාදැයි මට සරලව ලබා ගත නොහැකිද? අක්ෂර කේතීකරණ මත යැපීමක් පවතින්නේ ඇයි?

මන්ද එය කිරීමට සුදුසුම ක්‍රමය එය වන බැවිනි. stringසාරාංශයකි.

ඔබට අවලංගු අක්ෂර සහිත 'නූල්' තිබේ නම් කේතන ක්‍රමයක් භාවිතා කිරීමෙන් ඔබට කරදරයක් විය හැකි නමුත් එය සිදු නොවිය යුතුය. අවලංගු අක්ෂර සමඟ ඔබ ඔබේ නූලට දත්ත ලබා ගන්නේ නම් ඔබ එය වැරදිය. ආරම්භ කිරීමට ඔබ බොහෝ විට බයිට් අරා හෝ Base64 කේතන ක්‍රමයක් භාවිතා කළ යුතුය.

ඔබ භාවිතා කරන්නේ නම් System.Text.Encoding.Unicode, ඔබේ කේතය වඩාත් ප්‍රත්යාස්ථ වනු ඇත. ඔබේ කේතය ක්‍රියාත්මක වන පද්ධතියේ අවසානය ගැන ඔබ කරදර විය යුතු නැත . සීඑල්ආර් හි ඊළඟ අනුවාදය වෙනස් අභ්‍යන්තර අක්ෂර කේතීකරණයක් භාවිතා කරයිදැයි ඔබ කරදර විය යුතු නැත.

මම හිතන්නේ ප්‍රශ්නය ඔබට කේතන ක්‍රමය ගැන කරදර වීමට අවශ්‍ය නොවන්නේ ඇයි, නමුත් ඔබට එය නොසලකා හැර වෙනත් දෙයක් භාවිතා කිරීමට අවශ්‍ය ඇයි. කේතීකරණය යනු බයිට් අනුපිළිවෙලක නූලක් වියුක්ත කිරීම නිරූපණය කිරීමයි. System.Text.Encoding.Unicodeඔබට කුඩා එන්ඩියන් බයිට් ඇණවුම් කේතීකරණයක් ලබා දෙන අතර සෑම පද්ධතියකම එය දැන් සහ අනාගතයේදී සිදු කරනු ඇත.


ඇත්ත වශයෙන්ම C # හි ඇති නූලක් UTF-16 ට පමණක් සීමා නොවේ. සත්‍යය නම් එහි දෛශික 16-බිට් කේත ඒකක අඩංගු වන නමුත් මෙම 16-බිට් කේත ඒකක වලංගු UTF-16 ට පමණක් සීමා නොවේ. නමුත් ඒවා බිටු 16 ක් බැවින් ඒවා 8bit බවට පරිවර්තනය කිරීම සඳහා ඔබට කේතන ක්‍රමයක් (බයිට් ඇණවුමක්) අවශ්‍ය වේ. නූලකට ද්විමය කේතය (උදා: බිට්මැප් රූපයක්) ඇතුළුව යුනිකෝඩ් නොවන දත්ත ගබඩා කළ හැකිය. එය UTF-16 ලෙස අර්ථකථනය වන්නේ එවැනි අර්ථ නිරූපණය කරන I / O සහ පෙළ ආකෘති වල පමණි.
verdy_p

එබැවින් C # string එකක, ඔබට 0xFFFF හෝ 0xFFFE වැනි කේත ඒකකයක් UTF-16 හි අක්ෂර නොවන ඒවා වුවද ආරක්ෂිතව ගබඩා කළ හැකි අතර, ඔබට 0xDC00..0xDFFF හි කේත ඒකකයක් අනුගමනය නොකරන හුදකලා 0xD800 ගබඩා කළ හැකිය (එනම් UTF-16 හි වලංගු නොවන යුගලනය කරන ලද ආදේශක). ජාවාස්ක්‍රිප්ට් / ඊසීඑම්එස්ක්‍රිප්ට් සහ ජාවා හි ඇති නූල් සඳහා ද එම ප්‍රකාශයම අදාළ වේ.
verdy_p

ඔබ "GetBytes" භාවිතා කරන විට, ඇත්ත වශයෙන්ම ඔබ කේතීකරණයක් නියම නොකරයි, නමුත් ඔබ විසින් බයිට් දෙක දේශීය වශයෙන් නූල තුළ ගබඩා කර ඇති සෑම කේත ඒකකයක් සඳහාම විශේෂිත බයිට් එකක් ලබා ගැනීමට උපකල්පනය කරයි. ඔබ බයිට් වලින් නව නූලක් සාදන විට, ඔබට පරිවර්තකයක් ද අවශ්‍ය වේ, අවශ්‍යයෙන්ම යූටීඑෆ් -8 සිට යූටීඑෆ් -16 දක්වා නොවේ, ඔබට අමතර 0 ඉහළ බයිට් තුළට ඇතුළු කළ හැකිය, නැතහොත් බයිට් දෙකක් ඇසුරුම් කළ හැකිය (එම්එස්බී පළමු හෝ එල්එස්බී පළමු ඇණවුමේ) එකම 16-බිට් කේත ඒකකය. 16-බිටු නිඛිලවල අරා සඳහා නූල් සංයුක්ත ආකාරයකි. "අක්ෂර" සමඟ ඇති සම්බන්ධතාවය තවත් ගැටළුවක් වන අතර, සී # හි ඒවා තවමත් නූල් ලෙස නිරූපණය වන බැවින් ඒවා සත්‍ය වර්ග නොවේ
verdy_p

7

OP හි ප්‍රශ්නයට ආසන්නතම ප්‍රවේශය වන්නේ ටොම් බ්ලොජෙට්ස් ය, එය ඇත්ත වශයෙන්ම වස්තුව තුළට ගොස් බයිට් නිස්සාරණය කරයි. මම කිට්ටුම යැයි කියන්නේ එය සංගීත වස්තුව ක්‍රියාත්මක කිරීම මත රඳා පවතින බැවිනි.

"Can't I simply get what bytes the string has been stored in?"

ෂුවර්, නමුත් ප්‍රශ්නයේ මූලික දෝෂය පැන නගින්නේ එතැනිනි. නූල් යනු සිත්ගන්නා දත්ත ව්‍යුහයක් තිබිය හැකි වස්තුවකි. එය දැනටමත් සිදු වී ඇති බව අපි දනිමු, මන්ද එය යුගල නොකළ අන්‍යාගමිකයන් ගබඩා කිරීමට ඉඩ සලසයි. එය දිග ගබඩා කළ හැකිය. එය ඉක්මණින් ගණනය කිරීමට ඉඩ දෙන එක් එක් 'යුගල' අන්‍යාගමිකයින්ට දර්ශකයක් තබා ගත හැකිය. ආදිය මෙම අමතර බයිට් සියල්ලම අක්‍ෂර දත්තවල කොටසක් නොවේ.

ඔබට අවශ්‍ය වන්නේ අරාවෙහි ඇති එක් එක් චරිතයේ බයිට් ය. 'කේතන ක්‍රමය' එන්නේ එතැනිනි. පෙරනිමියෙන් ඔබට UTF-16LE ලැබෙනු ඇත. වට චාරිකාව හැරුණු විට ඔබට බයිට් ගැන සැලකිලිමත් නොවන්නේ නම්, ඔබට 'පෙරනිමිය' ඇතුළු ඕනෑම කේතන ක්‍රමයක් තෝරා ගත හැකි අතර පසුව එය නැවත පරිවර්තනය කළ හැකිය (පෙරනිමි කේතන ක්‍රමය, කේත ලකුණු, දෝෂ නිවැරදි කිරීම් වැනි පරාමිතීන් උපකල්පනය කරමින්) , නොගෙවූ අන්‍යාගමිකයන් වැනි දේ සඳහා අවසර දී ඇත.

නමුත් 'කේතන ක්‍රමය' මැජික් දක්වා තබන්නේ ඇයි? ඔබට ලැබිය යුතු බයිට් මොනවාදැයි දැන ගැනීමට කේතන ක්‍රමය සඳහන් නොකරන්නේ ඇයි?

"Why is there a dependency on character encodings?"

කේතනය කිරීම (මෙම සන්දර්භය තුළ) සරලවම අදහස් කරන්නේ ඔබේ නූල නියෝජනය කරන බයිට් ය. නූල් වස්තුවේ බයිට් නොවේ. ඔබට අවශ්‍ය වූයේ බයිට් එක ගබඩා කර ඇති බයිට් - මෙහි දී ප්‍රශ්නය බොළඳ ලෙස අසන ලදි. ඔබට අවශ්‍ය වූයේ නූල් නිරූපණය කරන පරස්පර අරාවක ඇති බයිට් වල මිස, වස්තුවක අඩංගු විය හැකි අනෙක් ද්විමය දත්ත නොවේ.

එයින් අදහස් කරන්නේ නූලක් ගබඩා කර ඇති ආකාරය අදාල නොවන බවයි. ඔබට බයිට් අරාවකින් බයිට් වලට “එන්කෝඩ්” කරන ලද නූලක් අවශ්‍යය.

ටොම් බ්ලොගට්ගේ පිළිතුරට මම කැමතියි ඔහු ඔබව 'නූල් වස්තුවේ බයිට්' දිශාවට ගෙන ගිය නිසා. එය ක්‍රියාත්මක කිරීම මත රඳා පවතී, නමුත් ඔහු අභ්‍යන්තරය දෙස බලන හෙයින්, නූලෙහි පිටපතක් නැවත සකස් කිරීම දුෂ්කර විය හැකිය.

සංකල්පීය මට්ටමින් නොමඟ යවන බැවින් මෙහර්දාඩ්ගේ ප්‍රතිචාරය වැරදිය. ඔබට තවමත් බයිට් ලැයිස්තුවක් ඇත, කේතනය කර ඇත. ඔහුගේ විශේෂිත විසඳුම වන්නේ නොගෙවූ අන්‍යාගමිකයින් ආරක්ෂා කර ගැනීමට ඉඩ සලසයි - මෙය ක්‍රියාත්මක කිරීම මත රඳා පවතී. ඔහුගේ විශේෂිත විසඳුම GetBytesපෙරනිමියෙන් යූටීඑෆ් -8 හි ඇති නූල ආපසු ලබා දෙන්නේ නම් නිවැරදිව බයිට් නිපදවන්නේ නැත .


මම මේ ගැන මගේ අදහස වෙනස් කර ඇත්තෙමි (මෙහර්දාඩ්ගේ විසඳුම) - මෙය නූල් වල බයිට් ලබා ගන්නේ නැත; ඒ වෙනුවට එය නූලෙන් සාදන ලද අරා අරා වල බයිට් ලබා ගනී. කේතීකරණය කුමක් වුවත්, c # හි ඇති වර්‍ග දත්ත කට්ටලය ස්ථාවර ප්‍රමාණයකි. මෙය ස්ථාවර දිග බයිට් අරාවක් නිපදවීමට ඉඩ සලසයි, තවද එය බයිට් අරාවේ ප්‍රමාණය මත පදනම්ව අරා ප්‍රතිනිෂ්පාදනය කිරීමට ඉඩ දෙයි. එබැවින් කේතීකරණය UTF-8 නම්, නමුත් සෑම වර්‍ගයක්ම විශාලතම utf8 වටිනාකමට සරිලන පරිදි බයිට් 6 ක් නම්, එය තවමත් ක්‍රියාත්මක වේ. එබැවින් ඇත්ත වශයෙන්ම - චරිතය කේතනය කිරීම වැදගත් නොවේ.

නමුත් පරිවර්තනයක් භාවිතා කරන ලදි - සෑම අක්‍ෂරයක්ම ස්ථාවර ප්‍රමාණයේ කොටුවකට දමා ඇත (c # ගේ අක්‍ෂර වර්ගය). කෙසේ වෙතත් එම නිරූපණය කුමක් ද යන්න ගැටළුවක් නොවේ, එය තාක්‍ෂණිකව OP සඳහා පිළිතුරකි. ඉතින් - ඔබ කෙසේ හෝ පරිවර්තනය කිරීමට යන්නේ නම් ... ඇයි 'කේතනය' නොකරන්නේ?


මෙම අක්ෂර ඇත සහය නොදක්වයි exapmle සඳහා UTF-8 හෝ UTF-16 හෝ UTF-32: 񩱠සහ (Char) 55906සහ (Char) 55655. එබැවින් ඔබ වැරදියි සහ මෙහර්දාඩ්ගේ පිළිතුර කුමන ආකාරයේ කේතීකරණ භාවිතා කරන්නේද යන්න සලකා බැලීමකින් තොරව ආරක්ෂිත පරිවර්තනයකි.
මොජ්ටාබා රෙසෙයියන්

රේමන්, අක්ෂර දැනටමත් යම් යුනිකෝඩ් අගයකින් නිරූපණය කර ඇති අතර සියලුම යුනිකෝඩ් අගයන් සියලු යූටීඑෆ් මගින් නිරූපණය කළ හැකිය. ඔබ කතා කරන්නේ කුමක් ද යන්න පිළිබඳ දීර් පැහැදිලි කිරීමක් තිබේද? එම අගයන් දෙක (හෝ 3 ..) පවතින්නේ කුමන චරිත කේතීකරණයේ ද?
ජෙරාඩ් ඔනිල්

ඒවා අවලංගු අක්ෂර වන අතර ඒවා කිසිදු කේතීකරණ පරාසයකින් සහය නොදක්වයි. මෙයින් අදහස් කරන්නේ ඒවා 100% නිෂ් .ල බවයි. කේතීකරණ නොසලකා ඕනෑම වර්ගයක නූල් එහි බයිට් අරාට සමාන බවට පරිවර්තනය කරන කේතයක් කිසිසේත් වැරදි විසඳුමක් නොවන අතර අපේක්ෂිත අවස්ථාවන්හිදී එහි භාවිතයන් ඇත.
මොජ්ටාබා රෙසෙයියන්

1
හරි, එහෙනම් මම හිතන්නේ ඔයාට ගැටලුව තේරෙන්නේ නැහැ. එය යුනිකෝඩ් අනුකූල අරාවක් බව අපි දනිමු - ඇත්ත වශයෙන්ම එය .net නිසා එය UTF-16 බව අපි දනිමු. එබැවින් එම චරිත එහි නොපවතිනු ඇත. අභ්‍යන්තර නිරූපණයන් වෙනස් වීම පිළිබඳ මගේ අදහස ඔබ සම්පූර්ණයෙන් කියවා නැත. නූල් යනු වස්තුවක් මිස කේතනය කරන ලද බයිට් අරාව නොවේ. ඒ නිසා මම ඔබේ අවසාන ප්‍රකාශයට එකඟ නොවෙමි. ඔබට අවශ්‍ය වන්නේ සියලුම යුනිකෝඩ් නූල් ඕනෑම යූටීඑෆ් කේතීකරණයකට පරිවර්තනය කිරීමයි. මෙය ඔබට අවශ්‍ය දේ නිවැරදිව කරයි.
ජෙරාඩ් ඔනිල්

වස්තූන් යනු දත්තවල අනුක්‍රමය වන අතර එය මුලින් පවතින වස්තුවක් විස්තර කරන බිටු අනුක්‍රමයයි. එබැවින් ක්‍රමලේඛන භාෂාවල ඇති සෑම දත්තයක්ම බයිට් පෙළකට පරිවර්තනය කළ හැකිය (සෑම බයිට් එකක්ම බිටු 8 ක් අර්ථ දක්වයි) ඔබට ඕනෑම වස්තුවක යම් තත්වයක් මතකයේ තබා ගැනීමට අවශ්‍ය විය හැකිය. ඔබට බයිට් අනුපිළිවෙලක් ගොනුවේ හෝ මතකයේ සුරැකීමට සහ රඳවා තබා ගත හැකි අතර එය සංඛ්‍යාංක, බිගින්ට්, පිංතූර, ඇස්කි නූල්, යූටීඑෆ් -8 නූල්, සංකේතාත්මක නූල් හෝ තැටියෙන් කියවීමෙන් පසු ඔබේම අර්ථ දක්වා ඇති දත්ත සමුදායක් ලෙස වාත්තු කළ හැකිය. එබැවින් වස්තූන් බයිට් අනුක්‍රමයට වඩා වෙනස් යැයි ඔබට පැවසිය නොහැක.
මොජ්ටාබා රෙසෙයියන්

6

ඔබ බවට පරිවර්තනය කිරීමට පහත දැක්වෙන කේතය භාවිතා කළ හැක stringවෙත byte array.NET දී

string s_unicode = "abcéabc";
byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(s_unicode);

3

ඔබට ඇත්තටම නූලක යටි බයිට් වල පිටපතක් අවශ්‍ය නම්, ඔබට පහත දැක්වෙන ශ්‍රිතය වැනි ශ්‍රිතයක් භාවිතා කළ හැකිය. කෙසේ වෙතත්, එයට හේතුව සොයා ගැනීමට කරුණාකර කියවා නොගත යුතුය .

[DllImport(
        "msvcrt.dll",
        EntryPoint = "memcpy",
        CallingConvention = CallingConvention.Cdecl,
        SetLastError = false)]
private static extern unsafe void* UnsafeMemoryCopy(
    void* destination,
    void* source,
    uint count);

public static byte[] GetUnderlyingBytes(string source)
{
    var length = source.Length * sizeof(char);
    var result = new byte[length];
    unsafe
    {
        fixed (char* firstSourceChar = source)
        fixed (byte* firstDestination = result)
        {
            var firstSource = (byte*)firstSourceChar;
            UnsafeMemoryCopy(
                firstDestination,
                firstSource,
                (uint)length);
        }
    }

    return result;
}

මෙම ශ්‍රිතය මඟින් ඔබේ නූලට යටින් ඇති බයිට් වල පිටපතක් ඉතා ඉක්මණින් ලැබෙනු ඇත. එම බයිට් ඔබේ පද්ධතියේ කේතනය කරන ඕනෑම ආකාරයකින් ඔබට ලැබෙනු ඇත. මෙම කේතන ක්‍රමය නිසැකවම පාහේ UTF-16LE වන නමුත් එය ඔබ සැලකිලිමත් නොවිය යුතු ක්‍රියාත්මක කිරීමේ විස්තරයකි.

ඇමතීමට එය ආරක්ෂිත, සරල හා විශ්වාසදායක වනු ඇත,

System.Text.Encoding.Unicode.GetBytes()

බොහෝ දුරට මෙය එකම ප්‍රති result ලයක් ලබා දෙනු ඇත, ටයිප් කිරීමට පහසුය, සහ බයිට් සෑම විටම ඇමතුමක් සමඟ වට-සංචාරය කරයි

System.Text.Encoding.Unicode.GetString()

3

මෙන්න මගේ අනාරක්ෂිත ක්රියාත්මක වේ Stringකිරීමට Byte[]පරිවර්තනය:

public static unsafe Byte[] GetBytes(String s)
{
    Int32 length = s.Length * sizeof(Char);
    Byte[] bytes = new Byte[length];

    fixed (Char* pInput = s)
    fixed (Byte* pBytes = bytes)
    {
        Byte* source = (Byte*)pInput;
        Byte* destination = pBytes;

        if (length >= 16)
        {
            do
            {
                *((Int64*)destination) = *((Int64*)source);
                *((Int64*)(destination + 8)) = *((Int64*)(source + 8));

                source += 16;
                destination += 16;
            }
            while ((length -= 16) >= 16);
        }

        if (length > 0)
        {
            if ((length & 8) != 0)
            {
                *((Int64*)destination) = *((Int64*)source);

                source += 8;
                destination += 8;
            }

            if ((length & 4) != 0)
            {
                *((Int32*)destination) = *((Int32*)source);

                source += 4;
                destination += 4;
            }

            if ((length & 2) != 0)
            {
                *((Int16*)destination) = *((Int16*)source);

                source += 2;
                destination += 2;
            }

            if ((length & 1) != 0)
            {
                ++source;
                ++destination;

                destination[0] = source[0];
            }
        }
    }

    return bytes;
}

එය පිළිගත් ඇන්වර්සර් එකට වඩා වේගවත් ය, එය එතරම් අලංකාර නොවුනත්. 10000000 පුනරාවර්තන වලට වඩා මගේ නැවතුම් ඔරලෝසු මිණුම් සලකුණු මෙන්න:

[Second String: Length 20]
Buffer.BlockCopy: 746ms
Unsafe: 557ms

[Second String: Length 50]
Buffer.BlockCopy: 861ms
Unsafe: 753ms

[Third String: Length 100]
Buffer.BlockCopy: 1250ms
Unsafe: 1063ms

එය භාවිතා කිරීම සඳහා, ඔබේ ව්‍යාපෘති ගොඩනැඟීමේ ගුණාංගවල “අනාරක්ෂිත කේතයට ඉඩ දෙන්න” ටික් කළ යුතුය. .NET Framework 3.5 ට අනුව, මෙම ක්‍රමය නූල් දිගුව ලෙසද භාවිතා කළ හැකිය:

public static unsafe class StringExtensions
{
    public static Byte[] ToByteArray(this String s)
    {
        // Method Code
    }
}

RuntimeHelpers.OffsetToStringData.NET හි ඉටේනියම් අනුවාදවල 8 ක ගුණනයක වටිනාකම තිබේද? වෙනත් ආකාරයකින් නොබැඳි කියවීම් නිසා මෙය අසාර්ථක වනු ඇත.
ජෝන් හැනා

ආයාචනා කිරීම සරල memcpyනොවේද? stackoverflow.com/a/27124232/659190
Jodrell

2

මෙය සරලව භාවිතා කරන්න:

byte[] myByte= System.Text.ASCIIEncoding.Default.GetBytes(myString);

2
... සහ 127 ට වඩා ඉහළින් පැනීම සමඟ සියලු අක්ෂර නැති කර ගන්න. මගේ මව් බසින් "Árvíztűrő tükörfúrógép" ලිවීම සම්පූර්ණයෙන්ම වලංගු වේ. System.Text.ASCIIEncoding.Default.GetBytes("Árvíztűrő tükörfúrógép.").ToString();ලබා "Árvizturo tukörfurogép."ගත නොහැකි නැතිවූ තොරතුරු නැවත ලබා දෙනු ඇත. (තවද ඔබ සියලු අක්ෂර ලිහිල් කරන ආසියානු භාෂා ගැන මම තවම සඳහන් කර නැත.)
mg30rg

2

පහත දැක්වෙන කාරණය නිසා නූල විවිධ ආකාර කිහිපයකින් බයිට් අරා බවට පරිවර්තනය කළ හැකිය: .නෙට් යුනිකෝඩ් සඳහා සහය දක්වයි, සහ යුනිකෝඩ් යූටීඑෆ් ලෙස හඳුන්වන වෙනස කේතීකරණ කිහිපයක් ප්‍රමිතිකරණය කරයි. ඒවාට විවිධ දිග බයිට් නිරූපණයන් ඇති නමුත් එම අර්ථයෙන් සමාන වන්නේ නූලක් කේතනය කළ විට එය නැවත නූලට කේතනය කළ හැකි නමුත් නූල එක් යූටීඑෆ් සමඟ කේතනය කර විවිධ යූටීඑෆ් උපකල්පනය කර විකේතනය කළ හැකි නම් ඉස්කුරුප්පු ඇරීමට හැකි නම් ඉහළට.

එසේම, .NET යුනිකෝඩ් නොවන කේතීකරණ සඳහා සහය දක්වයි, නමුත් ඒවා සාමාන්‍යයෙන් වලංගු නොවේ (වලංගු වන්නේ සීමිත යුනිකෝඩ් කේත ලක්ෂ්‍යයක් ASCII වැනි සත්‍ය නූලක භාවිතා කරන්නේ නම් පමණි). අභ්‍යන්තරව .NET UTF-16 සඳහා සහය දක්වයි, නමුත් ප්‍රවාහ නිරූපණය සඳහා UTF-8 සාමාන්‍යයෙන් භාවිතා වේ. එය අන්තර්ජාලය සඳහා සම්මත ප්‍රමිතියකි.

System.Text.Encodingවියුක්ත පංතියක් වන පංතියේ අනුපිළිවෙලින් බයිට් සහ ඩෙසරීකරණයට අනුක්‍රමණය කිරීම පුදුමයක් නොවේ ; එහි ව්‍යුත්පන්න පංති කොන්ක්‍රීට් කේතීකරණයට සහය දක්වයි : ASCIIEncodingසහ යූටීඑෆ් හතරක් (යූටීඑෆ් -16 System.Text.UnicodeEncodingසඳහා සහය දක්වයි)

Ref මෙම ලින්ක් එක.

භාවිතා කරමින් බයිට් සමූහයකට අනුක්‍රමිකකරණය සඳහා System.Text.Encoding.GetBytes. ප්‍රතිලෝම මෙහෙයුම් භාවිතය සඳහා System.Text.Encoding.GetChars. මෙම ශ්‍රිතය අක්ෂර මාලාවක් ලබා දෙයි, එබැවින් නූලක් ලබා ගැනීම සඳහා, නූල් සාදන්නෙකු භාවිතා කරන්න System.String(char[]).
මෙම පිටුව යොමු කරන්න.

උදාහරණයක්:

string myString = //... some string

System.Text.Encoding encoding = System.Text.Encoding.UTF8; //or some other, but prefer some UTF is Unicode is used
byte[] bytes = encoding.GetBytes(myString);

//next lines are written in response to a follow-up questions:

myString = new string(encoding.GetChars(bytes));
byte[] bytes = encoding.GetBytes(myString);
myString = new string(encoding.GetChars(bytes));
byte[] bytes = encoding.GetBytes(myString);

//how many times shall I repeat it to show there is a round-trip? :-)

2

එය ඔබට අවශ්‍ය බයිට් මත රඳා පවතී

මෙයට හේතුව, ටයිලර් ඉතා උචිත ලෙස පැවසූ පරිදි , "නූල් පිරිසිදු දත්ත නොවේ. ඒවාට තොරතුරු ද ඇත ." මෙම අවස්ථාවේ දී, තොරතුරු යනු නූල් නිර්මාණය කරන විට උපකල්පනය කරන ලද කේතන ක්‍රමයකි.

ඔබ ද්විමය දත්ත (පෙළ වෙනුවට) නූලක ගබඩා කර ඇතැයි උපකල්පනය කරන්න

මෙය පදනම් වී ඇත්තේ OP විසින් ඔහුගේම ප්‍රශ්නය පිළිබඳ අදහස් දැක්වීමෙන් වන අතර, භාවිතයේ දී OP ගේ ඉඟි මට වැටහෙන්නේ නම් එය නිවැරදි ප්‍රශ්නයයි.

ඉහත සඳහන් කළ උපකල්පිත කේතන ක්‍රමය නිසා ද්විමය දත්ත නූල්වල ගබඩා කිරීම බොහෝ විට වැරදි ප්‍රවේශයකි! එම ද්විමය දත්ත ගබඩා කර ඇති කුමන වැඩසටහනක් හෝ පුස්තකාලයක් string( byte[]වඩාත් සුදුසු විය හැකි අරාව වෙනුවට ) සටන ආරම්භ වීමට පෙර දැනටමත් අහිමි වී ඇත. REST ඉල්ලීමකින් / ප්‍රතිචාරයකින් හෝ නූල් සම්ප්‍රේෂණය කළ යුතු ඕනෑම දෙයකින් ඔවුන් ඔබට බයිට් යවන්නේ නම් , Base64 නිවැරදි ප්‍රවේශය වනු ඇත.

ඔබ නොදන්නා කේතීකරණයක් සහිත පෙළ නූලක් තිබේ නම්

අනෙක් සියල්ලෝම මෙම වැරදි ප්‍රශ්නයට වැරදියට පිළිතුරු දුන්හ.

නූල හොඳට පෙනේ නම්, කේතන ක්‍රමයක් තෝරන්න (ඊට වඩා යූටීඑෆ් සමඟ ආරම්භ වන එකක්), අනුරූප System.Text.Encoding.???.GetBytes()ශ්‍රිතය භාවිතා කරන්න , ඔබ තෝරාගත් කේතන ක්‍රමයට බයිට් ලබා දෙන්නේ කාටදැයි කියන්න.


2

ඔබ බයිට් සමඟ කුමක් කිරීමට අදහස් කරන්නේ දැයි විමසූ විට, ඔබ ප්‍රතිචාර දැක්වූයේ :

මම එය සංකේතනය කිරීමට යන්නෙමි. පරිවර්තනය නොකර මට එය සංකේතනය කළ හැකි නමුත් මෙහි සෙල්ලම් කිරීමට කේතීකරණ පැමිණෙන්නේ මන්දැයි දැන ගැනීමට මම තවමත් කැමතියි. මට කියන්න බයිට් දෙන්න.

මෙම සංකේතාත්මක දත්ත ජාලය හරහා යැවීමට, පසුව එය නැවත මතකය වෙත පැටවීමට හෝ වෙනත් ක්‍රියාවලියකට වාෂ්ප කිරීමට ඔබ අදහස් කළත්, ඔබ පැහැදිලිවම යම් අවස්ථාවක දී එය විකේතනය කිරීමට අදහස් කරයි . එවැනි අවස්ථාවකදී, පිළිතුර නම් ඔබ සන්නිවේදන ප්‍රොටෝකෝලයක් නිර්වචනය කිරීමයි. ඔබේ ක්‍රමලේඛන භාෂාවේ ක්‍රියාත්මක කිරීමේ තොරතුරු සහ ඒ හා සම්බන්ධ ධාවන වේලාවන් අනුව සන්නිවේදන ප්‍රොටෝකෝලයක් අර්ථ දැක්විය යුතු නොවේ . මේ සඳහා හේතු කිහිපයක් තිබේ:

  • ඔබට වෙනත් භාෂාවකින් හෝ ධාවන වේලාවක ක්‍රියාත්මක කරන ක්‍රියාවලියක් සමඟ සන්නිවේදනය කිරීමට අවශ්‍ය විය හැකිය. (මෙයට වෙනත් යන්ත්‍රයක ධාවනය වන සේවාදායකයක් හෝ ජාවාස්ක්‍රිප්ට් බ්‍රව්සර් සේවාදායකයෙකුට නූල යැවීම ඇතුළත් විය හැකිය.)
  • මෙම වැඩසටහන අනාගතයේදී වෙනත් භාෂාවකින් හෝ ධාවන කාලයකින් නැවත ක්‍රියාත්මක කළ හැකිය.
  • .NET ක්‍රියාත්මක කිරීම මඟින් නූල් වල අභ්‍යන්තර නිරූපණය වෙනස් විය හැකිය. මෙය දුරදිග නොබලා යැයි ඔබ සිතනු ඇත, නමුත් මෙය ඇත්ත වශයෙන්ම ජාවා 9 හි සිදු වූයේ මතක භාවිතය අඩු කිරීම සඳහා ය. හේතුවක් නැත .නෙට් හට එය අනුගමනය කළ නොහැක. ස්කීට් යෝජනා කරන්නේ අද යූටීඑෆ් -16 ප්‍රශස්ත නොවන බවයි. යුනිකෝඩ් හි ඉමොජි සහ අනෙකුත් කොටස් වල නිරූපණය සඳහා බයිට් 2 කට වඩා අවශ්‍ය වන අතර අනාගතයේදී අභ්‍යන්තර නියෝජනය වෙනස් විය හැකි බව වැඩි කරයි.

සන්නිවේදනය සඳහා (සම්පූර්ණයෙන්ම අසමාන ක්‍රියාවලියක් සමඟ හෝ අනාගතයේදී එකම වැඩසටහනක් සමඟ), ඔබේ ප්‍රොටෝකෝලය සමඟ වැඩ කිරීමේ දුෂ්කරතාවය අවම කිරීම හෝ වැරදීමකින් දෝෂ ඇති කිරීම සඳහා ඔබ දැඩි ලෙස අර්ථ දැක්විය යුතුය . .NET හි අභ්‍යන්තර නිරූපණය මත පදනම්ව දැඩි, පැහැදිලි හෝ ස්ථාවර අර්ථ දැක්වීමක් සහතික නොවේ. සම්මත කේතන ක්‍රමයක් යනු අනාගතයේදී ඔබව අසමත් නොවන දැඩි අර්ථ දැක්වීමකි.

වෙනත් වචන වලින් කිවහොත්, කේතීකරණයක් නියම නොකර අනුකූලතාව සඳහා ඔබේ අවශ්‍යතාවය සපුරාලිය නොහැක .

ඔබ විය හැක නිසැකව .NET අභ්යන්තර හෝ වෙනත් කිසියම් හේතුවක් නිසා එය භාවිතා කරයි නිසා, නමුත් ඔබට වඩා අනුව පැහැදිලි ලෙසම සංකේතවත් බව තෝරා ඔබගේ කේතය ගනනාවකින්ම එම ආගමට හරවා ඉටු කිරීමට අවශ්ය ඔබ සැලකිය යුතු වඩා හොඳ ඔබේ ක්රියාවලිය කිරිමටද බව සොයා නම් කෙලින්ම UTF-16 ලෙස භාවිතා කිරීම තෝරාගෙන .NET හි අභ්‍යන්තර ක්‍රියාත්මක කිරීම මත.

එබැවින් කේතීකරණයක් තෝරා එය භාවිතා කරන්න:

using System.Text;

// ...

Encoding.Unicode.GetBytes("abc"); # UTF-16 little endian
Encoding.UTF8.GetBytes("abc")

ඔබට පෙනෙන පරිදි, ඔබේම පා er ක / ලේඛක ක්‍රම ක්‍රියාත්මක කිරීමට වඩා සංකේතාත්මක වස්තු භාවිතා කිරීම අඩු කේතයකි.


1

ක්‍රම දෙකක්:

public static byte[] StrToByteArray(this string s)
{
    List<byte> value = new List<byte>();
    foreach (char c in s.ToCharArray())
        value.Add(c.ToByte());
    return value.ToArray();
}

සහ,

public static byte[] StrToByteArray(this string s)
{
    s = s.Replace(" ", string.Empty);
    byte[] buffer = new byte[s.Length / 2];
    for (int i = 0; i < s.Length; i += 2)
        buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
    return buffer;
}

මම ඉහළට වඩා බොහෝ විට පතුල භාවිතා කිරීමට නැඹුරු වෙමි, වේගය සඳහා ඒවා මිණුම් සලකුණු කර නැත.


4
බහු බයිට් අක්ෂර ගැන කුමක් කිව හැකිද?
ඇග්නෙල් කුරියන්

c.ToByte () පුද්ගලිකයි: S
Khodor

@AgnelKurian Msdn පවසන්නේ "මෙම ක්‍රමය මඟින් අත්සන් නොකළ චාර් වස්තුවේ සංඛ්‍යා කේතය නිරූපණය කරන අත්සන් නොකළ බයිට් අගයක් ලබා දෙයි. .NET රාමුව තුළ, චාර් වස්තුවක් බිටු 16 ක අගයක් වේ. මෙයින් අදහස් කරන්නේ නැවත පැමිණීමට මෙම ක්‍රමය සුදුසු බවයි ASCII අක්ෂර පරාසය තුළ හෝ යුනිකෝඩ් සී 0 පාලක සහ මූලික ලතින්, සහ සී 1 පාලක සහ ලතින් -1 පරිපූරක පරාසයන්හි U + 0000 සිට U + 00FF දක්වා සංඛ්‍යාත්මක කේත. ”
mg30rg

1
bytes[] buffer = UnicodeEncoding.UTF8.GetBytes(string something); //for converting to UTF then get its bytes

bytes[] buffer = ASCIIEncoding.ASCII.GetBytes(string something); //for converting to ascii then get its bytes
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.