Comment puis-je convertir un string
à un byte[]
dans .NET (C #) sans spécifier manuellement un codage spécifique?
Je vais crypter la chaîne. Je peux le crypter sans conversion, mais j'aimerais toujours savoir pourquoi l'encodage vient jouer ici.
Aussi, pourquoi l'encodage devrait-il même être pris en considération? Je ne peux pas simplement obtenir dans quels octets la chaîne a été stockée? Pourquoi existe-t-il une dépendance sur les encodages de caractères?
c#
.net
string
character-encoding
Agnel Kurian
la source
la source
Réponses:
Contrairement aux réponses ici, vous n'avez PAS à vous soucier de l'encodage si les octets n'ont pas besoin d'être interprétés!
Comme vous l'avez mentionné, votre objectif est, simplement, «d'obtenir dans quels octets la chaîne a été stockée» .
(Et, bien sûr, pour pouvoir reconstruire la chaîne à partir des octets.)
Pour ces objectifs, je ne comprends vraiment pas pourquoi les gens continuent de vous dire que vous avez besoin des encodages. Vous n'avez certainement PAS besoin de vous soucier des encodages pour cela.
Faites simplement ceci à la place:
Tant que votre programme (ou d'autres programmes) n'essaie pas d' interpréter les octets d'une manière ou d'une autre, ce que vous n'avez évidemment pas mentionné que vous avez l'intention de faire, alors il n'y a rien de mal à cette approche! S'inquiéter des encodages rend votre vie plus compliquée sans raison réelle.
Avantage supplémentaire à cette approche:
Peu importe si la chaîne contient des caractères invalides, car vous pouvez toujours obtenir les données et reconstruire la chaîne d'origine de toute façon!
Il sera codé et décodé de la même manière, car vous ne regardez que les octets .
Si vous avez utilisé un encodage spécifique, cependant, cela vous aurait posé des problèmes avec l'encodage / décodage de caractères invalides.
la source
GetString
etGetBytes
nécessité d'exécuter sur un système avec le même boutisme au travail. Vous ne pouvez donc pas l'utiliser pour obtenir des octets que vous souhaitez transformer en chaîne ailleurs. J'ai donc du mal à trouver une situation où je voudrais utiliser cela.Cela dépend de l'encodage de votre chaîne ( ASCII , UTF-8 , ...).
Par exemple:
Un petit échantillon pourquoi l'encodage est important:
ASCII n'est tout simplement pas équipé pour gérer les caractères spéciaux.
En interne, le framework .NET utilise UTF-16 pour représenter les chaînes, donc si vous voulez simplement obtenir les octets exacts que .NET utilise, utilisez
System.Text.Encoding.Unicode.GetBytes (...)
.Voir Encodage de caractères dans le .NET Framework (MSDN) pour plus d'informations.
la source
La réponse acceptée est très, très compliquée. Utilisez les classes .NET incluses pour cela:
Ne réinventez pas la roue si vous n'êtes pas obligé ...
la source
System.Text.Encoding.Unicode
être équivalent à la réponse de Mehrdad.System.Text.Encoding.Unicode.GetBytes
serait probablement plus précis.la source
Vous devez prendre en compte l'encodage, car 1 caractère peut être représenté par 1 ou plusieurs octets (jusqu'à environ 6), et différents encodages traiteront ces octets différemment.
Joel a une publication à ce sujet:
la source
C'est une question populaire. Il est important de comprendre ce que l'auteur de la question pose, et qu'il est différent de ce qui est probablement le besoin le plus courant. Pour décourager l'utilisation abusive du code là où il n'est pas nécessaire, j'ai répondu le plus tard en premier.
Besoin commun
Chaque chaîne a un jeu de caractères et un encodage. Lorsque vous convertissez un
System.String
objet en tableau,System.Byte
vous avez toujours un jeu de caractères et un codage. Pour la plupart des utilisations, vous savez quel jeu de caractères et quel encodage vous avez besoin et .NET facilite la «copie avec conversion». Choisissez simplement laEncoding
classe appropriée .La conversion peut avoir besoin de gérer les cas où le jeu de caractères ou l'encodage cible ne prend pas en charge un caractère qui se trouve dans la source. Vous avez le choix: exception, substitution ou saut. La politique par défaut consiste à remplacer un «?».
De toute évidence, les conversions ne sont pas nécessairement sans perte!
Remarque: Pour
System.String
le jeu de caractères source est Unicode.La seule chose déroutante est que .NET utilise le nom d'un jeu de caractères pour le nom d'un codage particulier de ce jeu de caractères.
Encoding.Unicode
devrait être appeléEncoding.UTF16
.C'est tout pour la plupart des utilisations. Si c'est ce dont vous avez besoin, arrêtez de lire ici. Consultez l'article amusant de Joel Spolsky si vous ne comprenez pas ce qu'est un encodage.
Besoin spécifique
Maintenant, l'auteur de la question demande: "Chaque chaîne est stockée sous forme de tableau d'octets, n'est-ce pas? Pourquoi ne puis-je pas simplement avoir ces octets?"
Il ne veut aucune conversion.
De la spécification C # :
Donc, nous savons que si nous demandons la conversion nulle (c'est-à-dire de UTF-16 en UTF-16), nous obtiendrons le résultat souhaité:
Mais pour éviter la mention des encodages, il faut faire autrement. Si un type de données intermédiaire est acceptable, il existe un raccourci conceptuel pour cela:
Cela ne nous donne pas le type de données souhaité, mais la réponse de Mehrdad montre comment convertir ce tableau Char en un tableau d'octets à l'aide de BlockCopy . Cependant, cela copie la chaîne deux fois! Et, il utilise aussi explicitement du code spécifique au codage: le type de données
System.Char
.La seule façon d'accéder aux octets réels dans lesquels la chaîne est stockée est d'utiliser un pointeur. L'
fixed
instruction permet de prendre l'adresse des valeurs. De la spécification C #:Pour ce faire, le compilateur écrit du code sautant les autres parties de l'objet chaîne avec
RuntimeHelpers.OffsetToStringData
. Donc, pour obtenir les octets bruts, créez simplement un pointeur sur la chaîne et copiez le nombre d'octets nécessaires.Comme l'a souligné @CodesInChaos, le résultat dépend de l'endianité de la machine. Mais l'auteur de la question ne s'en préoccupe pas.
la source
Length
propriété [deString
] renvoie le nombre d'Char
objets dans cette instance, pas le nombre de caractères Unicode." Votre exemple de code est donc correct tel qu'il est écrit.new String(new []{'\uD800', '\u0030'})
Globalization.SortKey
, extrait leKeyData
, et emballe les octets résultants de chacun dans unString
[deux octets par caractère, MSB d'abord ], l'appelString.CompareOrdinal
aux chaînes résultantes sera beaucoup plus rapide que l'appelSortKey.Compare
aux instances deSortKey
, ou même en faisant appelmemcmp
à ces instances. Compte tenu de cela, je me demande pourquoiKeyData
renvoie unByte[]
plutôt qu'unString
?La première partie de votre question (comment obtenir les octets) a déjà été répondue par d'autres: regardez dans l'
System.Text.Encoding
espace de noms.Je vais répondre à votre question de suivi: pourquoi avez-vous besoin de choisir un encodage? Pourquoi ne pouvez-vous pas obtenir cela de la classe de chaîne elle-même?
La réponse est en deux parties.
Tout d'abord, les octets utilisés en interne par la classe de chaîne n'ont pas d'importance , et chaque fois que vous supposez qu'ils le font, vous introduisez probablement un bogue.
Si votre programme est entièrement dans le monde .Net, vous n'avez pas à vous soucier d'obtenir des tableaux d'octets pour les chaînes, même si vous envoyez des données sur un réseau. Utilisez plutôt la sérialisation .Net pour vous soucier de la transmission des données. Vous ne vous souciez plus des octets réels: le formateur de sérialisation le fait pour vous.
D'un autre côté, que se passe-t-il si vous envoyez ces octets quelque part que vous ne pouvez pas garantir extraira des données d'un flux sérialisé .Net? Dans ce cas, vous devez absolument vous soucier de l'encodage, car ce système externe se soucie évidemment. Encore une fois, les octets internes utilisés par la chaîne n'ont pas d'importance: vous devez choisir un encodage pour pouvoir être explicite sur cet encodage du côté de la réception, même s'il s'agit du même encodage utilisé en interne par .Net.
Je comprends que dans ce cas, vous préférerez peut-être utiliser les octets réels stockés par la variable de chaîne en mémoire lorsque cela est possible, avec l'idée que cela pourrait économiser du travail en créant votre flux d'octets. Cependant, je vous suggère que ce n'est tout simplement pas important par rapport à vous assurer que votre sortie est comprise à l'autre extrémité, et pour garantir que vous devez être explicite avec votre encodage. De plus, si vous voulez vraiment faire correspondre vos octets internes, vous pouvez déjà simplement choisir le
Unicode
codage et obtenir ces économies de performances.Ce qui m'amène à la deuxième partie ... choisir l'
Unicode
encodage, c'est dire à .Net d'utiliser les octets sous-jacents. Vous devez choisir cet encodage, car lorsque de nouveaux Unicode-Plus sortent, le runtime .Net doit être libre pour utiliser ce modèle d'encodage plus récent et meilleur sans interrompre votre programme. Mais, pour le moment (et l'avenir prévisible), le simple choix de l'encodage Unicode vous donne ce que vous voulez.Il est également important de comprendre que votre chaîne doit être réécrite sur le fil, ce qui implique au moins une certaine traduction du motif binaire même lorsque vous utilisez un codage correspondant . L'ordinateur doit prendre en compte des éléments tels que Big vs Little Endian, l'ordre des octets réseau, la mise en paquets, les informations de session, etc.
la source
Juste pour démontrer que son de Mehrdrad réponse œuvres, son approche peut même persister les caractères de substitution non appariés (dont beaucoup avaient portées contre ma réponse, mais dont tout le monde sont également coupables, par exemple
System.Text.Encoding.UTF8.GetBytes
,System.Text.Encoding.Unicode.GetBytes
; ces méthodes de codage ne peuvent pas persister la forte substitution caractèresd800
par exemple, et ceux qui viennent simplement remplacer les caractères de substitution élevés avec une valeurfffd
):Production:
Essayez cela avec System.Text.Encoding.UTF8.GetBytes ou System.Text.Encoding.Unicode.GetBytes , ils remplaceront simplement les caractères de substitution élevés par la valeur fffd
Chaque fois qu'il y a un mouvement dans cette question, je pense toujours à un sérialiseur (que ce soit de Microsoft ou d'un composant tiers) qui peut conserver des chaînes même s'il contient des caractères de substitution non appariés; Je google ceci de temps en temps: sérialisation caractère de substitution non apparié .NET . Cela ne me fait pas perdre le sommeil, mais c'est un peu ennuyeux quand de temps en temps quelqu'un commente ma réponse qu'elle est erronée, mais leurs réponses sont également imparfaites en ce qui concerne les caractères de substitution non appariés.
Bon sang, Microsoft aurait juste dû utiliser
System.Buffer.BlockCopy
dans sonBinaryFormatter
ツ谢谢!
la source
System.Buffer.BlockCopy
interne, tous les arguments des gens de l'encodage-plaidoyer seront sans objetFFFD
sur ce caractère. Si vous souhaitez effectuer une manipulation de chaîne manuelle, utilisez un char [] comme recommandé.System.String
est une séquence immuable deChar
; .NET a toujours permis à unString
objet d'être construit à partir de anyChar[]
et d'exporter son contenu vers unChar[]
contenant les mêmes valeurs, même si l'originalChar[]
contient des substituts non appariés.Essayez ceci, beaucoup moins de code:
la source
System.Text.Encoding.UTF8.GetBytes("Árvíztűrő tükörfúrógép);
et pleurez! Cela fonctionnera, maisSystem.Text.Encoding.UTF8.GetBytes("Árvíztűrő tükörfúrógép").Length != System.Text.Encoding.UTF8.GetBytes("Arvizturo tukorfurogep").Length
pendant que"Árvíztűrő tükörfúrógép".Length == "Arvizturo tukorfurogep".Length
Eh bien, j'ai lu toutes les réponses et elles portaient sur l'utilisation de l'encodage ou sur la sérialisation qui supprime les substituts non appariés.
C'est mauvais lorsque la chaîne, par exemple, provient de SQL Server où elle a été construite à partir d'un tableau d'octets stockant, par exemple, un hachage de mot de passe. Si nous en supprimons quelque chose, il stockera un hachage non valide et si nous voulons le stocker en XML, nous voulons le laisser intact (car le rédacteur XML lâche une exception sur tout substitut non apparié qu'il trouve).
J'utilise donc le codage Base64 des tableaux d'octets dans de tels cas, mais bon, sur Internet, il n'y a qu'une seule solution à cela en C #, et il y a un bug et c'est seulement dans un sens, j'ai donc corrigé le bug et réécrit procédure. Voilà, futurs googleurs:
la source
Convert.ToBase64String(arr);
pour les conversions base64byte[] (data) <-> string (serialized data to store in XML file)
. Mais pour obtenir l'initiale,byte[] (data)
je devais faire quelque chose avec unString
contenant des données binaires (c'est la façon dont MSSQL me les a renvoyées). Donc les fonctions ci-dessus sont pourString (binary data) <-> byte[] (easy accessible binary data)
.Parce qu'il n'y a rien de tel que "les octets de la chaîne".
Une chaîne (ou plus généralement, un texte) est composée de caractères: lettres, chiffres et autres symboles. C'est tout. Les ordinateurs, cependant, ne savent rien des personnages; ils ne peuvent gérer que des octets. Par conséquent, si vous souhaitez stocker ou transmettre du texte à l'aide d'un ordinateur, vous devez transformer les caractères en octets. Comment tu fais ça? Voici où les encodages entrent en scène.
Un codage n'est rien d'autre qu'une convention pour traduire des caractères logiques en octets physiques. L'encodage le plus simple et le plus connu est ASCII, et c'est tout ce dont vous avez besoin si vous écrivez en anglais. Pour d'autres langues, vous aurez besoin d'encodages plus complets, l'une des saveurs Unicode étant le choix le plus sûr de nos jours.
Donc, en bref, essayer "d'obtenir les octets d'une chaîne sans utiliser de codages" est aussi impossible que "écrire un texte sans utiliser de langue".
Soit dit en passant, je vous recommande fortement (et à quiconque d'ailleurs) de lire ce petit morceau de sagesse: le minimum absolu que chaque développeur de logiciels doit absolument, positivement, connaître à propos de l'Unicode et des jeux de caractères (pas d'excuses!)
la source
C # pour convertir un
string
enbyte
tableau:la source
la source
Vous pouvez utiliser le code suivant pour la conversion entre chaîne et tableau d'octets.
la source
Avec l'avènement de la
Span<T>
version C # 7.2, la technique canonique pour capturer la représentation mémoire sous-jacente d'une chaîne dans un tableau d'octets gérés est la suivante:La reconversion devrait être un non-démarrage, car cela signifie que vous interprétez en fait les données d'une manière ou d'une autre, mais dans un souci d'exhaustivité:
Les noms
NonPortableCast
etDangerousGetPinnableReference
devraient étayer l'argument selon lequel vous ne devriez probablement pas faire cela.Notez que l'utilisation de
Span<T>
nécessite l'installation du package System.Memory NuGet .Quoiqu'il en soit, la réelle question initiale et des commentaires de suivi impliquent que la mémoire sous - jacente n'est pas « interprété » (que je suppose que des moyens ne sont pas modifiés ou lire au - delà de la nécessité de l' écrire comme-est), ce qui indique qu'une certaine mise en œuvre de la
Stream
classe doit être utilisé au lieu de raisonner sur les données sous forme de chaînes.la source
Je ne suis pas sûr, mais je pense que la chaîne stocke ses informations sous forme de tableau de caractères, ce qui est inefficace avec des octets. Plus précisément, la définition d'un caractère est «représente un caractère Unicode».
prenez cet exemple d'exemple:
Notez que la réponse Unicode est de 14 octets dans les deux cas, tandis que la réponse UTF-8 n'est que de 9 octets pour le premier et de 7 pour le second.
Donc, si vous voulez juste que les octets
Encoding.Unicode
soient utilisés par la chaîne, utilisez simplement , mais cela sera inefficace avec l'espace de stockage.la source
Le problème clé est qu'un glyphe dans une chaîne prend 32 bits (16 bits pour un code de caractère) mais qu'un octet ne dispose que de 8 bits. Un mappage un à un n'existe pas, sauf si vous vous limitez aux chaînes qui ne contiennent que des caractères ASCII. System.Text.Encoding a de nombreuses façons de mapper une chaîne en octet [], vous devez en choisir une qui évite la perte d'informations et qui est facile à utiliser par votre client lorsqu'il a besoin de mapper l'octet [] en chaîne .
Utf8 est un encodage populaire, il est compact et sans perte.
la source
Utilisation:
Le résultat est:
la source
Moyen le plus rapide
EDIT comme Makotosan l'a commenté, c'est maintenant le meilleur moyen:
la source
Une chaîne en .NET représente le texte comme une séquence d'unités de code UTF-16, donc les octets sont déjà encodés en mémoire en UTF-16.
Réponse de Mehrdad
Vous pouvez utiliser la réponse de Mehrdad , mais elle utilise en fait un encodage car les caractères sont UTF-16. Il appelle ToCharArray qui en regardant la source crée un
char[]
et y copie directement la mémoire. Il copie ensuite les données dans un tableau d'octets qui est également alloué. Donc, sous le capot, il copie deux fois les octets sous-jacents et alloue un tableau de caractères qui n'est pas utilisé après l'appel.La réponse de Tom Blodget
La réponse de Tom Blodget est 20 à 30% plus rapide que Mehrdad car elle ignore l'étape intermédiaire d'allouer un tableau de caractères et de copier les octets, mais elle nécessite que vous compiliez avec l'
/unsafe
option. Si vous ne voulez absolument pas utiliser l'encodage, je pense que c'est la voie à suivre. Si vous placez votre connexion de chiffrement dans lefixed
bloc, vous n'avez même pas besoin d'allouer un tableau d'octets séparé et de copier les octets dans celui-ci.Parce que c'est la bonne façon de procéder.
string
est une abstraction.L'utilisation d'un encodage peut vous poser des problèmes si vous avez des «chaînes» avec des caractères non valides, mais cela ne devrait pas se produire. Si vous obtenez des données dans votre chaîne avec des caractères non valides, vous vous trompez. Vous devriez probablement utiliser un tableau d'octets ou un encodage Base64 pour commencer.
Si vous utilisez
System.Text.Encoding.Unicode
, votre code sera plus résistant. Vous n'avez pas à vous soucier de l' endianité du système sur lequel votre code sera exécuté. Vous n'avez pas à vous inquiéter si la prochaine version du CLR utilisera un encodage de caractères interne différent.Je pense que la question n'est pas pourquoi vous voulez vous soucier de l'encodage, mais pourquoi vous voulez l'ignorer et utiliser autre chose. Le codage est censé représenter l'abstraction d'une chaîne dans une séquence d'octets.
System.Text.Encoding.Unicode
vous donnera un petit codage de l'ordre des octets endian et effectuera la même chose sur tous les systèmes, maintenant et à l'avenir.la source
L'approche la plus proche de la question de l'OP est celle de Tom Blodget, qui va en fait dans l'objet et extrait les octets. Je dis le plus proche car cela dépend de la mise en œuvre de l'objet String.
Bien sûr, mais c'est là que l'erreur fondamentale de la question se pose. La chaîne est un objet qui pourrait avoir une structure de données intéressante. Nous le savons déjà, car il permet de stocker des substituts non appariés. Il pourrait stocker la longueur. Il pourrait garder un pointeur sur chacun des substituts «appariés» permettant un comptage rapide. Etc. Tous ces octets supplémentaires ne font pas partie des données de caractères.
Ce que vous voulez, ce sont les octets de chaque caractère dans un tableau. Et c'est là que «l'encodage» entre en jeu. Par défaut, vous obtiendrez UTF-16LE. Si vous ne vous souciez pas des octets eux-mêmes, sauf pour l'aller-retour, vous pouvez choisir n'importe quel encodage, y compris le `` défaut '', et le reconvertir plus tard (en supposant les mêmes paramètres tels que le codage par défaut, les points de code, les corrections de bogues). , les choses autorisées telles que les substituts non appariés, etc.
Mais pourquoi laisser «l'encodage» à la magie? Pourquoi ne pas spécifier l'encodage pour savoir quels octets vous allez obtenir?
L'encodage (dans ce contexte) signifie simplement les octets qui représentent votre chaîne. Pas les octets de l'objet chaîne. Vous vouliez les octets dans lesquels la chaîne a été stockée - c'est là que la question a été posée naïvement. Vous vouliez les octets de chaîne dans un tableau contigu qui représentent la chaîne, et non toutes les autres données binaires qu'un objet chaîne peut contenir.
Ce qui signifie que la façon dont une chaîne est stockée n'est pas pertinente. Vous voulez une chaîne "codée" en octets dans un tableau d'octets.
J'aime la réponse de Tom Bloget parce qu'il vous a emmené dans la direction des «octets de l'objet chaîne». Cela dépend de l'implémentation, et comme il regarde les composants internes, il peut être difficile de reconstituer une copie de la chaîne.
La réponse de Mehrdad est fausse parce qu'elle est trompeuse au niveau conceptuel. Vous avez toujours une liste d'octets, encodée. Sa solution particulière permet de conserver les substituts non appariés - cela dépend de l'implémentation. Sa solution particulière ne produirait pas les octets de la chaîne avec précision si elle
GetBytes
renvoyait la chaîne en UTF-8 par défaut.J'ai changé d'avis à ce sujet (la solution de Mehrdad) - cela n'obtient pas les octets de la chaîne; il récupère plutôt les octets du tableau de caractères créé à partir de la chaîne. Quel que soit le codage, le type de données char en c # est de taille fixe. Cela permet de produire un tableau d'octets de longueur cohérente et de reproduire le tableau de caractères en fonction de la taille du tableau d'octets. Donc, si l'encodage était UTF-8, mais chaque caractère était de 6 octets pour accueillir la plus grande valeur utf8, cela fonctionnerait toujours. Donc en effet - l'encodage du personnage n'a pas d'importance.
Mais une conversion a été utilisée - chaque caractère a été placé dans une boîte de taille fixe (type de caractère de c #). Cependant, quelle est cette représentation n'a pas d'importance, ce qui est techniquement la réponse au PO. Donc - si vous voulez quand même convertir ... Pourquoi ne pas 'encoder'?
la source
&(Char) 55906
&(Char) 55655
. Vous pouvez donc vous tromper et la réponse de Mehrdad est une conversion sûre sans tenir compte du type d'encodage utilisé.Vous pouvez utiliser le code suivant pour convertir un
string
en unbyte array
dans .NETla source
Si vous voulez vraiment une copie des octets sous-jacents d'une chaîne, vous pouvez utiliser une fonction comme celle qui suit. Cependant, vous ne devriez pas lire la suite pour savoir pourquoi.
Cette fonction vous fournira une copie des octets sous-jacents à votre chaîne, assez rapidement. Vous obtiendrez ces octets de quelque manière qu'ils encodent sur votre système. Cet encodage est presque certainement UTF-16LE mais c'est un détail d'implémentation dont vous ne devriez pas avoir à vous soucier.
Il serait plus sûr, plus simple et plus fiable d'appeler simplement,
Selon toute vraisemblance, cela donnera le même résultat, sera plus facile à taper et les octets seront toujours aller-retour avec un appel à
la source
Voici ma mise en œuvre dangereuse de
String
laByte[]
conversion:Il est beaucoup plus rapide que celui qui est accepté, même s'il n'est pas aussi élégant qu'il est. Voici mes benchmarks chronomètres sur 10000000 itérations:
Pour l'utiliser, vous devez cocher "Autoriser le code non sécurisé" dans les propriétés de construction de votre projet. Selon .NET Framework 3.5, cette méthode peut également être utilisée comme extension de chaîne:
la source
RuntimeHelpers.OffsetToStringData
un multiple de 8 est-elle sur les versions Itanium de .NET? Sinon, cela échouera en raison des lectures non alignées.memcpy
? stackoverflow.com/a/27124232/659190Utilisez simplement ceci:
la source
System.Text.ASCIIEncoding.Default.GetBytes("Árvíztűrő tükörfúrógép.").ToString();
renverra des"Árvizturo tukörfurogép."
informations perdues qui ne peuvent pas être récupérées. (Et je n'ai pas encore mentionné les langues asiatiques où vousLa chaîne peut être convertie en tableau d'octets de différentes manières, en raison du fait suivant: .NET prend en charge Unicode et Unicode standardise plusieurs codages de différence appelés UTF. Ils ont des longueurs de représentation d'octets différentes mais sont équivalents en ce sens que lorsqu'une chaîne est codée, elle peut être codée en retour dans la chaîne, mais si la chaîne est codée avec un UTF et décodée dans l'hypothèse de différents UTF si elle peut être vissée vers le haut.
En outre, .NET prend en charge les encodages non Unicode, mais ils ne sont pas valides dans le cas général (ne seront valides que si un sous-ensemble limité de points de code Unicode est utilisé dans une chaîne réelle, comme ASCII). En interne, .NET prend en charge UTF-16, mais pour la représentation en flux, UTF-8 est généralement utilisé. C'est également une norme de facto pour Internet.
Sans surprise, la sérialisation de la chaîne en un tableau d'octets et la désérialisation sont prises en charge par la classe
System.Text.Encoding
, qui est une classe abstraite; ses classes dérivées prennent en charge les encodages concrets:ASCIIEncoding
et quatre UTF (System.Text.UnicodeEncoding
prend en charge UTF-16)Ref ce lien.
Pour la sérialisation vers un tableau d'octets à l'aide de
System.Text.Encoding.GetBytes
. Pour l'opération inverse, utilisezSystem.Text.Encoding.GetChars
. Cette fonction renvoie un tableau de caractères, donc pour obtenir une chaîne, utilisez un constructeur de chaîneSystem.String(char[])
.Réf cette page.
Exemple:
la source
Cela dépend de ce que vous voulez pour les octets
En effet, comme l'a si bien dit Tyler , "les chaînes ne sont pas de pures données. Elles contiennent également des informations ." Dans ce cas, les informations sont un codage supposé lors de la création de la chaîne.
En supposant que vous avez des données binaires (plutôt que du texte) stockées dans une chaîne
Ceci est basé sur le commentaire d'OP sur sa propre question, et c'est la bonne question si je comprends les indices d'OP sur le cas d'utilisation.
Le stockage de données binaires dans des chaînes est probablement la mauvaise approche en raison du codage supposé mentionné ci-dessus! Quel que soit le programme ou la bibliothèque stocké ces données binaires dans un
string
(au lieu d'unbyte[]
tableau qui aurait été plus approprié) a déjà perdu la bataille avant de commencer. S'ils vous envoient les octets dans une demande / réponse REST ou quoi que ce soit qui doit transmettre des chaînes, Base64 serait la bonne approche.Si vous avez une chaîne de texte avec un encodage inconnu
Tout le monde a répondu incorrectement à cette question incorrecte.
Si la chaîne semble bonne telle
System.Text.Encoding.???.GetBytes()
quelle , choisissez simplement un encodage (de préférence un commençant par UTF), utilisez la fonction correspondante et dites à qui vous donnez les octets à quel encodage vous avez choisi.la source
Lorsqu'on vous a demandé ce que vous comptiez faire des octets, vous avez répondu :
Que vous ayez l'intention d'envoyer ces données chiffrées sur le réseau, de les recharger en mémoire ultérieurement ou de les transférer dans un autre processus, vous avez clairement l'intention de les déchiffrer à un moment donné. Dans ce cas, la réponse est que vous définissez un protocole de communication. Un protocole de communication ne doit pas être défini en termes de détails d'implémentation de votre langage de programmation et de son runtime associé. Il y a plusieurs raisons à cela:
Pour communiquer (avec un processus complètement disparate ou avec le même programme à l'avenir), vous devez définir votre protocole strictement pour minimiser la difficulté de travailler avec lui ou de créer accidentellement des bogues. Dépendre de la représentation interne de .NET n'est pas une définition stricte, claire ou même garantie d'être cohérente. Un encodage standard est une définition stricte qui ne vous fera pas défaut à l'avenir.
En d'autres termes, vous ne pouvez pas satisfaire votre exigence de cohérence sans spécifier un codage.
Vous pouvez certainement choisir d'utiliser UTF-16 directement si vous trouvez que votre processus fonctionne beaucoup mieux car .NET l'utilise en interne ou pour toute autre raison, mais vous devez choisir explicitement cet encodage et effectuer ces conversions explicitement dans votre code plutôt que de dépendre sur l'implémentation interne de .NET.
Choisissez donc un encodage et utilisez-le:
Comme vous pouvez le voir, il est également en fait moins de code d'utiliser simplement les objets de codage intégrés que d'implémenter vos propres méthodes de lecture / écriture.
la source
Deux façons:
Et,
J'ai tendance à utiliser celui du bas plus souvent que le haut, je ne les ai pas comparés pour la vitesse.
la source
la source