Issue while encoding a string - c#

I'm developing an application where at some point i need an encoded stream of bytes based on the given user output.
Something like
Encoding sysEncode = System.Text.Encoding.GetEncoding(850);
byte[] dataToEncrypt = sysEncode.GetBytes(m_oStrActivation);
However when i extract the string from the byte stream i get the encrypted string as
W?????e?????W?X????;??2????W???????#
Is there any way(type of Encoding/equivalent) i can restrict these question marks and allow only plain scrambled alphanumeric characters ?

From m_oStrActivation and you mentioning "encryption" I assume that you're writing some kind of activation/licensing code. If this is the case, you're doing it wrong. A correct way to do this is to use a hash function over your activation data.
You can then transform this string into Base64 string using Convert.ToBase64String() method.

Related

how to fix corrupt japanese character encoding

i have the following string that i know is suppose to be displayed as Japanese text
25“ú‚¨“¾‚ȃAƒ‹ƒeƒBƒƒbƒgƒRƒXƒZƒbƒg‹L”O
is there any way to decode and re-encode the text so it displays properly? i already tried using shift-jis but it did not produce a readable string.
string main = "25“ú‚¨“¾‚ȃAƒ‹ƒeƒBƒƒbƒgƒRƒXƒZƒbƒg‹L”O.zip";
byte[] mainBytes = System.Text.Encoding.GetEncoding("shift-jis").GetBytes(main);
string jpn = System.Text.Encoding.GetEncoding("shift-jis").GetString(mainBytes);
thanks!
I think that the original is Shift-JIS, but you didn't show how you did try. So here is my try to re-code it::
string s1 = "25“ú‚¨“¾‚ȃAƒ‹ƒeƒBƒƒbƒgƒRƒXƒZƒbƒg‹L”O";
byte[] bs = Encoding.GetEncoding(1252).GetBytes(s1);
string s2 = Encoding.GetEncoding(932).GetString(bs);
And s2 is now "25日お得なアルティャbトコスセット記念", that looks a lot more like Japanese.
What I assume it that some byte array that represent text Shift-JIS encoded, what read by using a different encoding, maybe Windows-1252. So first I try to get back the original byte array. Then I use the proper encoding to get the correct text.
A few notes about my code:
1252 is the numeric ID for Windows-1252, the most usually used-by-mistake encoding. But this is just a guess, you can try with other encodings and see if it makes more sense.
932 is de numeric ID for Shift-JIS (you can also use the string name). This is also a guess, but likely right.
Take into account that using a wrong encoding is not generally a reversible procedure so there may be characters that are lost in the translation.

Convert file (or byte[]) into ascii, then convert that ascii back into the original file

I'm using an old technology called RTTY to send data (it's basically fancy Morse Code) over radio.
RTTY can only transmit ascii characters
What I want to do is convert a file such as a small jpg or something similar into a block of ascii text, send the characters over radio, then convert the characters on the remote end back into the original file.
Some help getting started would be great.
I know I need to use StreamReader but then how can I convert the byte[] into an encoded ascii string that I can then 'decode'.
I know i need to use streamreader but then how can I convert the byte[] into an encoded ascii string that I can then 'decode'
Basically, you want to use a Base64 conversion. It will inflate the size of the data, but it guarantees that you'll be able to round-trip the original binary data.
Use Convert.ToBase64String to convert a byte[] into a string, and Convert.FromBase64String to do the reverse.

How to convert between string and byte[] without losing integrity

I know how to convert from a string to byte[] in C#. In this particular case, I'm working with the string representation of an HMAC-SHA256 key. Let's say the string representation of this key I get from an OpenID OP is:
"81FNybKWfcM539vVGtJrXRmoVMxNmZHY3OgUro8+pZ8="
I convert it to byte[] like this:
byte[] myByteArr = Encoding.UTF8.GetBytes("81FNybKWfcM539vVGtJrXRmoVMxNmZHY3OgUro8+pZ8=");
The problem I have with that is that it seems to be losing the original data. If I take the byte array from the previous step and convert it back to a string, it's different from the original string.
string check = Convert.ToBase64String(myByteArr);
check ends up being:
"ODFGTnliS1dmY001Mzl2Vkd0SnJYUm1vVk14Tm1aSFkzT2dVcm84K3BaOD0="
which is obviously not the same as the original string representation I started with.
With crypto keys, always use Convert.FromBase64String and Convert.ToBase64String. That way you'll be doing it the standard way and will not lose bytes due to encoding problems. Base 64 string may not be space efficient but it is the preferred method for storage and transport of keys in many schemes.
Here is a quick verification:
byte[] myByteArr = Convert.FromBase64String("81FNybKWfcM539vVGtJrXRmoVMxNmZHY3OgUro8+pZ8=");
string check = Convert.ToBase64String(myByteArr);
Console.WriteLine(check);
// Writes: 81FNybKWfcM539vVGtJrXRmoVMxNmZHY3OgUro8+pZ8=
The first function (Encoding.UTF8.GetBytes) takes a string (of any kind) and returns a byte[] that represents that string in a particular encoding -- in your case, UTF8.
The second function (Convert.ToBase64String) takes a byte array (of any kind) and returns a string in base64 format so that you can store this binary data in any ASCII-compatible field using only printable characters.
These functions are not counterparts. It looks like the string you're getting is a base64-encoded string. If this is the case, use Convert.FromBase64String to get the byte[] that it represents, not Encoding.UTF8.GetBytes.
The bytes you get when using byte[] Encoding.GetBytes(string) and decoding a base64 string are not the same things. The former gives you the bytes that represent the string. You however want to decode a base64 string back to the bytes it represents. In that case you want to use Convert.FromBase64String().
string encoded = "81FNybKWfcM539vVGtJrXRmoVMxNmZHY3OgUro8+pZ8=";
byte[] decoded = Convert.FromBase64String(encoded); // this gives the bytes that the encoded string represents
The encoding classes have a GetString method, to convert it from a byte array back to a string.
If you used the UTF8 encoding to create the byte array, you should use the same coding to get it back again.
var original = "81FNybKWfcM539vVGtJrXRmoVMxNmZHY3OgUro8+pZ8=";
var byteArray = Encoding.UTF8.GetBytes(original);
var copy = Encoding.UTF8.GetString(byteArray);
bool match = (copy == original); // This returns true

Store binary data string into byte array using c#

I have a webservice that returns a binary data as a string. Using C# code how can I store it in byte array? Is this the right way?
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] bytes = encoding.GetBytes(inputString);
Actually, this didn't work. Let me explain it more:
the web service code converts a string (containing XSLFO data) into byte array using utf8 encoding. In my web service response I only see data something like "PGZvOnJvb3QgeG1sbnM6Zm89Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML0Zvcm1hdCIgeG1sbnM­6eGY9Imh0dHA6Ly93d3cuZWNyaW9uLmNvbS94Zi8xLjAiIHhtbG5zOm1zeHNsPSJ1c==". Actually I would like to have the original string value that was converted into byte[] in the service. Not sure if it possible?
No, that's a bad idea.
Unless the input data was originally text, trying to use Encoding is a bad idea. The web service should be using something like base64 to encode it - at which point you can use Convert.FromBase64String to get the original binary data back.
Basically, treating arbitrary binary data as if it were encoded text is a quick way to lose data. When you need to represent binary data in a string, you should use base64, hex or something similar.
This may mean you need to change the web service as well, of course - if it's creating the string by simply treating the binary data as UTF-8-encoded text, it's broken to start with.
If the string is encoded in UTF8 Encoding, then yes that is the correct way. If it is in Unicode it is very similar:
System.Text.Unicode encoding = new System.Text.Unicode();
byte[] bytes = encoding.GetBytes(inputString);
Base64Encoding is a little different:
byte[] bytes = Convert.FromBase64String(inputString);

Encrypt a filename in C# without including unusable chars in the resulting string

I want to encrypt a filename but ensure that the encrypted filename doesn't contain any of the characters that are not allowed (on a windows system) in filenames.
The string also needs to be able to be decrypted back to the original filename (so you can't just filter out the invalid characters after the encryption).
To my knowledge the unusable characters are \ / : * ? " > < |. I'm aware of System.IO.Path.InvalidPathChars but I don't know of an encryption method that will avoid those characters.
You can convert the filename, or the encrypted output, to MIME Base64 encoding. I don't believe that standard uses any of the prohibited characters. (Even if it does, you can .Replace() prohibited characters with nonprohibited ones.)
For example, your question base64'd is:
c2UgdGhpcyBiYXNlNjQgc2FtcGxlIGRlY29kZXIgYW5kIGVuY29kZXIgdG86DQpGcmVuZCBDemVj
aCBsaW5rcw0KDQpMYXN0IG1pbnV0ZSBaYWplemR5DQpBa2NpZSBCaWJsZQ0KTGV2bmUgcG5ldQ0K
RmFrdHVyYQ0KU2VhcmNoIEN6ZWNoDQpIcnksIFZ5enZhbmVuaSBuYSBtb2JpbA0KT3RoZXINCg0K
ICAgICogRGVjb2RlIGJhc2U2NCBzdHJpbmdzIChiYXNlNjQgc3RyaW5nIGxvb2tzIGxpa2UgWVRN
ME5ab21JekkyT1RzbUl6TTBOVHVlWVE9PSkNCiAgICAqIERlY29kZSBhIGJhc2U2NCBlbmNvZGVk
IGZpbGUgKGZvciBleGFtcGxlIElDTyBmaWxlcyBvciBmaWxlcyBmcm9tIE1JTUUgbWVzc2FnZSkN
CiAgICAqIENvbnZlcnQgc291cmNlIHRleHQgZGF0YSBmcm9tIHNldmVyYWwgY29kZSBwYWdlcyBh
bmQgZW5jb2RlIHRoZW0gdG8gYSBiYXNlNjQgc3RyaW5nIG9yIGEgZmlsZQ0KDQoNCiAgICAgIFRo
ZSBGb3JtLlNpemVMaW1pdCBpcyAxMDAwMDAwMGJ5dGVzLiBQbGVhc2UsIGRvIG5vdCBwb3N0IG1v
cmUgZGF0YSB1c2luZyB0aGlzIGZvcm0uDQoNCiAgICAgVHlwZSAob3IgY29weS1wYXN0ZSkgc29t
ZSB0ZXh0IHRvIGEgdGV4dGJveCBiZWxsb3cuIFRoZSB0ZXh0IGNhbiBiZSBCYXNlNjQ=
As #Tom notes, you can base64 encode the file name. However, .NET's base64 methods include the slash character, so you'll need to replace that.
var encryptedFilename = GetEncryptedFileName();
var encodedFileName = Convert.ToBase64String(Encoding.UTF8.GetBytes(encryptedFilename));
var encodedAndEscapedFilename = encodedFileName.Replace('/', '-');
You can then do basically the same thing in reverse to get the original name (using Convert.FromBase64String and Encoding.UTF8.GetString).
There is no resulting 'string', all encryption transformations result in byte[] not in string. There are string representations of byte[], like the well knows hex (0xBAADF00D) or Base64. Probably base64 is the most appropiate, just use Convert.ToBase64String and Convert.FromBase64String.
That being said encrypting a file name seems like a very bad idea. File names are by definition index lookup keys and with encryption you will loose any lookup ability. You will have to scan the entire disk/folder and decrypt each file name just to find out the file you want. Note that you cannot rely on a known encrypted value (eg. if I seek 'file.txt' I encrypt 'file.txt' and then search for the encrypted name) because encryption has to use a random IV value (which is appended to the encryption result). Failure to properly randomize the IV will result in cribs. Yet succesful salting the key (good random IV) will make the result unsearchable.
As Remus stated above there is no resulting 'string', all encryption transformations result in byte[] not in string.
I generally take an encryption output byte array, and call BitConverter.ToString(Bytes); to convert it to hex, though this does result in a FF-D0-FF-D1 format. If a plain hex string is required, just run a .Replace("-", "");
e.g.
return
BitConverter.ToString(AESEncryption.Encrypt(token,
key)).Replace("-", "");
(AESEncryption is a simple custom built wrapper around RijndaelManaged)
Decryption isn't quite as neat, a bit brute force, but still simple
private byte[] FromHexString(string encryptedToken)
{
List<byte> bytes = new List<byte>();
for (int i = 0; i <= encryptedToken.Length; i+=2)
{
try
{
bytes.Add((byte)Int32.Parse(encryptedToken.Substring(i, 2), System.Globalization.NumberStyles.HexNumber));
}
catch //whatever exception
{
//handle
}
}
return bytes.ToArray();
}
My answer was to convert the encrypted code to HEX. The benefit to this was compatibility between ASP, ASPX, SQL, VB, C#, and Javascript.Another benefit was that I could use the encryption of my choice without worrying about the output.

Categories