I am trying to "decode" this following Base64 string:
OBFZDTcPCxlCKhdXCQ0kMQhKPh9uIgYIAQxALBtZAwUeOzcdcUEeW0dMO1kbPElWCV1ISFFKZ0kdWFlLAURPZhEFQVseXVtPOUUICVhMAzcfZ14AVEdIVVgfAUIBWVpOUlAeaUVMXFlKIy9rGUN0VF08Oz1POxFfTCcVFw1LMQNbBQYWAQ==
This is what I know about the string itself:
The original string is first passed through the following code:
private static string m000493(string p0, string p1)
{
StringBuilder builder = new StringBuilder(p0);
StringBuilder builder2 = new StringBuilder(p1);
StringBuilder builder3 = new StringBuilder(p0.Length);
int num = 0;
Label_0084:
while (num < builder.Length)
{
int num2 = 0;
while (num2 < p1.Length)
{
if ((num == builder.Length) || (num2 == builder2.Length))
{
MessageBox.Show("EH?");
goto Label_0084;
}
char ch = builder[num];
char ch2 = builder2[num2];
ch = (char)(ch ^ ch2);
builder3.Append(ch);
num2++;
num++;
}
}
return m0001cd(builder3.ToString());
}
The p1 part in the code is supposed to be the string "_p0lizei.".
It is then converted to a Base64 string by the following code:
private static string m0001cd(string p0)
{
string str2;
try
{
byte[] buffer = new byte[p0.Length];
str2 = Convert.ToBase64String(Encoding.UTF8.GetBytes(p0));
}
catch (Exception exception)
{
throw new Exception("Error in base64Encode" + exception.Message);
}
return str2;
}
The question is, how do I decode the Base64 string so that I can find out what the original string is?
Simple:
byte[] data = Convert.FromBase64String(encodedString);
string decodedString = Encoding.UTF8.GetString(data);
The m000493 method seems to perform some kind of XOR encryption. This means that the same method can be used for both encoding and decoding the text. All you have to do is reverse m0001cd:
string p0 = Encoding.UTF8.GetString(Convert.FromBase64String("OBFZDT..."));
string result = m000493(p0, "_p0lizei.");
// result == "gaia^unplugged^Ta..."
with return m0001cd(builder3.ToString()); changed to return builder3.ToString();.
// Decode a Base64 string to a string
public static string DecodeBase64(string value)
{
if(string.IsNullOrEmpty(value))
return string.Empty;
var valueBytes = System.Convert.FromBase64String(value);
return System.Text.Encoding.UTF8.GetString(valueBytes);
}
Related
I'm writing a console app that will grab some data from a Chrome extension and email me a report. The data is stored as JSON in the localstorage file, which is a sqlite database. If I copy the hex and convert it online at http://string-functions.com/hex-string.aspx it converts to the JSON properly. But, no matter how I try to do it in C#, it looks like this:
Here's my main portion of code:
static void Main(string[] args)
{
var dbLocation = ConfigurationManager.AppSettings["dbLocation"];
using (var connection = new SQLiteConnection(string.Format("Data Source={0};Version=3;", dbLocation)))
{
connection.Open();
var response = connection.Query<string>("SELECT hex(value) FROM ItemTable WHERE key = 'state'").Single();
var json = ConvertHex(response);
//var response = JsonConvert.DeserializeObject<ChromeData>(json);
}
}
For the ConvertHex function here's everything I have tried, all of which have the same result. These are pulled from various other StackOverflow answers.
public static string ConvertHex(String hexString)
{
try
{
string ascii = string.Empty;
for (int i = 0; i < hexString.Length; i += 2)
{
String hs = string.Empty;
hs = hexString.Substring(i, 2);
uint decval = System.Convert.ToUInt32(hs, 16);
char character = System.Convert.ToChar(decval);
ascii += character;
}
return ascii;
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
return string.Empty;
}
private static string HexString2Ascii(string hexString)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= hexString.Length - 2; i += 2)
{
sb.Append(Convert.ToString(Convert.ToChar(Int32.Parse(hexString.Substring(i, 2), System.Globalization.NumberStyles.HexNumber))));
}
return sb.ToString();
}
public static byte[] FromHex(string hex)
{
hex = hex.Replace("-", "");
byte[] raw = new byte[hex.Length / 2];
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
return raw;
}
static string HexStringToString(string hexString)
{
if (hexString == null || (hexString.Length & 1) == 1)
{
throw new ArgumentException();
}
var sb = new StringBuilder();
for (var i = 0; i < hexString.Length; i += 2)
{
var hexChar = hexString.Substring(i, 2);
sb.Append((char)Convert.ToByte(hexChar, 16));
}
return sb.ToString();
}
Any help is appreciated. Thanks!
Try below code.
Change the try block of ConvertHex as said below.
Look into comments for the details.
public static string ConvertHex(String hexString)
{
try
{
//DECLARE A VARIABLE TO RETURN
string ascii = string.Empty;
//SPLIT THE HEX STRING BASED ON SPACE (ONE SPACE BETWEEN TWO NUMBERS)
string[] hexSplit = hexString.Split(' ');
//LOOP THROUGH THE EACH HEX SPLIT
foreach (String hex in hexSplit)
{
// CONVERT THE NUMBER TO BASE 16
int value = Convert.ToInt32(hex, 16);
// GET THE RESPECTIVE CHARACTER
string stringValue = Char.ConvertFromUtf32(value);
char charValue = (char)value;
//APPEND THE STRING
ascii += charValue;
}
//RETURN THE STRING
return ascii;
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
return string.Empty;
}
I'm working on French String in .NET
Decoding a Mail body , I receive "Chasn=C3=A9 sur illet"
I would like to get "Chasné sur illet"
and i don't find any solution aver 2 days web search.
C# ou VB.NET
Can anyone helps me ?
thanks
Or the easiest of all, just use the QuotedPrintableDecoder from my MimeKit library:
static string DecodeQuotedPrintable (string input, string charset)
{
var decoder = new QuotedPrintableDecoder ();
var buffer = Encoding.ASCII.GetBytes (input);
var output = new byte[decoder.EstimateOutputLength (buffer.Length)];
int used = decoder.Decode (buffer, 0, buffer.Length, output);
var encoding = Encoding.GetEncoding (charset);
return encoding.GetString (output, 0, used);
}
Note that the other answers above assume the decoded content will be ASCII or UTF-8, but that isn't necessarily the case. You'll need to get the charset parameter from the Content-Type header of the MIME part that you are decoding.
Of course... if you don't know how to get that info, you could simply use my awesome MailKit library to get the MIME part from IMAP and have it do all of this work for you.
This is UTF8 encoding.
Using this post:
http://www.dpit.co.uk/decoding-quoted-printable-email-in-c/
Here is the code (don't forget to accept the answer if helped):
using System;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(DecodeQuotedPrintable("Chasn=C3=A9 sur illet"));
Console.ReadKey();
}
static string DecodeQuotedPrintable(string input)
{
var occurences = new Regex(#"(=[0-9A-Z][0-9A-Z])+", RegexOptions.Multiline);
var matches = occurences.Matches(input);
foreach (Match m in matches)
{
byte[] bytes = new byte[m.Value.Length / 3];
for (int i = 0; i < bytes.Length; i++)
{
string hex = m.Value.Substring(i * 3 + 1, 2);
int iHex = Convert.ToInt32(hex, 16);
bytes[i] = Convert.ToByte(iHex);
}
input = input.Replace(m.Value, Encoding.UTF8.GetString(bytes));
}
return input.Replace("=rn", "");
}
}
}
From : https://stackoverflow.com/a/36803911/6403521
My solution :
[TestMethod]
public void TestMethod1()
{
Assert.AreEqual("La Bouichère", quotedprintable("La Bouich=C3=A8re", "utf-8"));
Assert.AreEqual("Chasné sur illet", quotedprintable("Chasn=C3=A9 sur illet", "utf-8"));
Assert.AreEqual("é è", quotedprintable("=C3=A9 =C3=A8", "utf-8"));
}
private string quotedprintable(string pStrIn, string encoding)
{
String strOut = pStrIn.Replace("=\r\n", "");
// Find the first =
int position = strOut.IndexOf("=");
while (position != -1)
{
// String before the =
string leftpart = strOut.Substring(0, position);
// get the QuotedPrintable String in a ArrayList
System.Collections.ArrayList hex = new System.Collections.ArrayList();
// The first Part
hex.Add(strOut.Substring(1 + position, 2));
// Look for the next parts
while (position + 3 < strOut.Length && strOut.Substring(position + 3, 1) == "=")
{
position = position + 3;
hex.Add(strOut.Substring(1 + position, 2));
}
// In the hex Array, we have two items
// Convert using the GetEncoding Function
byte[] bytes = new byte[hex.Count];
for (int i = 0; i < hex.Count; i++)
{
bytes[i] = System.Convert.ToByte(new string(((string)hex[i]).ToCharArray()), 16);
}
string equivalent = System.Text.Encoding.GetEncoding(encoding).GetString(bytes);
// Part of the orignal String after the last QP Symbol
string rightpart = strOut.Substring(position + 3);
// Re build the String
strOut = leftpart + equivalent + rightpart;
// find the new QP Position
position = leftpart.Length + equivalent.Length;
if (rightpart.Length == 0)
{
position = -1;
}
else
{
position = strOut.IndexOf("=", position + 1);
}
}
return strOut;
}
We had an issue with this method - that it is VERY slow.
The following enhanced performance A LOT
public static string FromMailTransferEncoding(this string messageText, Encoding enc, string transferEncoding)
{
if (string.IsNullOrEmpty(transferEncoding))
return messageText;
if ("quoted-printable".Equals(transferEncoding.ToLower()))
{
StringBuilder sb = new StringBuilder();
string delimitorRegEx = #"=[\r][\n]";
string[] parts = Regex.Split(messageText, delimitorRegEx);
foreach (string part in parts)
{
string subPart = part;
Regex occurences = new Regex(#"(=[0-9A-Z][0-9A-Z])+", RegexOptions.Multiline);
MatchCollection matches = occurences.Matches(subPart);
foreach (Match m in matches)
{
byte[] bytes = new byte[m.Value.Length / 3];
for (int i = 0; i < bytes.Length; i++)
{
string hex = m.Value.Substring(i * 3 + 1, 2);
int iHex = Convert.ToInt32(hex, 16);
bytes[i] = Convert.ToByte(iHex);
}
subPart = occurences.Replace(subPart, enc.GetString(bytes), 1);
}
sb.Append(subPart);
}
return sb.ToString();
}
return messageText;
}
static string ConverFromHex(string source)
{
string target = string.Empty;
int startPos = source.IndexOf('=', 0);
int prevStartPos = 0;
while (startPos >= 0)
{
// concat with substring from source
target += source.Substring(prevStartPos, startPos - prevStartPos);
// next offset
startPos++;
// update prev pos
prevStartPos = startPos;
// get substring
string hexString = source.Substring(startPos, 2);
// get int equiv
int hexNum = 0;
if (int.TryParse(hexString, System.Globalization.NumberStyles.AllowHexSpecifier, System.Globalization.CultureInfo.InvariantCulture, out hexNum))
{
// add to target string
target += (char)hexNum;
// add hex length
prevStartPos += 2;
}
// next occurence
startPos = source.IndexOf('=', startPos);
}
// add rest of source
target += source.Substring(prevStartPos);
return target;
}
This question already has answers here:
how do I set a character at an index in a string in c#?
(7 answers)
Closed 5 years ago.
String does not have ReplaceAt(), and I'm tumbling a bit on how to make a decent function that does what I need. I suppose the CPU cost is high, but the string sizes are small so it's all ok
Use a StringBuilder:
StringBuilder sb = new StringBuilder(theString);
sb[index] = newChar;
theString = sb.ToString();
The simplest approach would be something like:
public static string ReplaceAt(this string input, int index, char newChar)
{
if (input == null)
{
throw new ArgumentNullException("input");
}
char[] chars = input.ToCharArray();
chars[index] = newChar;
return new string(chars);
}
This is now an extension method so you can use:
var foo = "hello".ReplaceAt(2, 'x');
Console.WriteLine(foo); // hexlo
It would be nice to think of some way that only required a single copy of the data to be made rather than the two here, but I'm not sure of any way of doing that. It's possible that this would do it:
public static string ReplaceAt(this string input, int index, char newChar)
{
if (input == null)
{
throw new ArgumentNullException("input");
}
StringBuilder builder = new StringBuilder(input);
builder[index] = newChar;
return builder.ToString();
}
... I suspect it entirely depends on which version of the framework you're using.
string s = "ihj";
char[] array = s.ToCharArray();
array[1] = 'p';
s = new string(array);
Strings are immutable objects, so you can't replace a given character in the string.
What you can do is you can create a new string with the given character replaced.
But if you are to create a new string, why not use a StringBuilder:
string s = "abc";
StringBuilder sb = new StringBuilder(s);
sb[1] = 'x';
string newS = sb.ToString();
//newS = "axc";
I suddenly needed to do this task and found this topic.
So, this is my linq-style variant:
public static class Extensions
{
public static string ReplaceAt(this string value, int index, char newchar)
{
if (value.Length <= index)
return value;
else
return string.Concat(value.Select((c, i) => i == index ? newchar : c));
}
}
and then, for example:
string instr = "Replace$dollar";
string outstr = instr.ReplaceAt(7, ' ');
In the end I needed to utilize .Net Framework 2, so I use a StringBuilder class variant though.
If your project (.csproj) allow unsafe code probably this is the faster solution:
namespace System
{
public static class StringExt
{
public static unsafe void ReplaceAt(this string source, int index, char value)
{
if (source == null)
throw new ArgumentNullException("source");
if (index < 0 || index >= source.Length)
throw new IndexOutOfRangeException("invalid index value");
fixed (char* ptr = source)
{
ptr[index] = value;
}
}
}
}
You may use it as extension method of String objects.
public string ReplaceChar(string sourceString, char newChar, int charIndex)
{
try
{
// if the sourceString exists
if (!String.IsNullOrEmpty(sourceString))
{
// verify the lenght is in range
if (charIndex < sourceString.Length)
{
// Get the oldChar
char oldChar = sourceString[charIndex];
// Replace out the char ***WARNING - THIS CODE IS WRONG - it replaces ALL occurrences of oldChar in string!!!***
sourceString.Replace(oldChar, newChar);
}
}
}
catch (Exception error)
{
// for debugging only
string err = error.ToString();
}
// return value
return sourceString;
}
at a recent interview I attended, the programming question that was asked was this. Write a function that will take as input two strings. The output should be the result of concatenation.
Conditions: Should not use StringBuffer.Append or StringBuilder.Append or string objects for concatenation;that is, they want me to implement the pseudo code implementation of How StringBuilder or StringBuffer's Append function works.
This is what I did:
static char[] AppendStrings(string input, string append)
{
char[] inputCharArray = input.ToCharArray();
char[] appendCharArray = append.ToCharArray();
char[] outputCharArray = new char[inputCharArray.Length + appendCharArray.Length];
for (int i = 0; i < inputCharArray.Length; i++)
{
outputCharArray[i] = inputCharArray[i];
}
for (int i = 0; i < appendCharArray.Length; i++)
{
outputCharArray[input.Length + i] = appendCharArray[i];
}
return outputCharArray;
}
While this is a working solution, is there a better way of doing things?
is LINQ legal? strings are just can be treated as an enumeration of chars, so they can be used with LINQ (even though there is some cost involved, see comments):
string a = "foo";
string b = "bar";
string c = new string(a.AsEnumerable().Concat(b).ToArray());
or with your method signature:
static char[] AppendStrings(string input, string append)
{
return input.AsEnumerable().Concat(append).ToArray();
}
You can call CopyTo:
char[] output = new char[a.Length + b.Length];
a.CopyTo(0, output, 0, a.Length);
b.CopyTo(0, output, a.Length, b.Length);
return new String(output);
If they don't like that, call .ToCharArray().CopyTo(...).
You can also cheat:
return String.Join("", new [] { a, b });
return String.Format("{0}{1}", a, b);
var writer = new StringWriter();
writer.Write(a);
writer.Write(b);
return writer.ToString();
I would've done something like the following (argument checking omitted for brevity)
public static string Append(string left, string right) {
var array = new char[left.Length + right.Length];
for (var i = 0; i < left.Length; i++) {
array[i] = left[i];
}
for (var i = 0; i < right.Length; i++) {
array[i + left.Length] = right[i];
}
return new string(array);
}
In Java you can just use concat which does not use StringBuilder or StringBuffer.
String a = "foo";
String b = "bar";
String ab = a.concat(b);
The source for String.concat(String) from Oracle's JDK.
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);
}
java default support "+" for append string
String temp="some text";
for(int i=0;i<10;i++)
{
temp=temp+i;
}
Or
temp=temp+" some other text"
How can I convert this string:
This string contains the Unicode character Pi(π)
into an escaped ASCII string:
This string contains the Unicode character Pi(\u03a0)
and vice versa?
The current Encoding available in C# converts the π character to "?". I need to preserve that character.
This goes back and forth to and from the \uXXXX format.
class Program {
static void Main( string[] args ) {
string unicodeString = "This function contains a unicode character pi (\u03a0)";
Console.WriteLine( unicodeString );
string encoded = EncodeNonAsciiCharacters(unicodeString);
Console.WriteLine( encoded );
string decoded = DecodeEncodedNonAsciiCharacters( encoded );
Console.WriteLine( decoded );
}
static string EncodeNonAsciiCharacters( string value ) {
StringBuilder sb = new StringBuilder();
foreach( char c in value ) {
if( c > 127 ) {
// This character is too big for ASCII
string encodedValue = "\\u" + ((int) c).ToString( "x4" );
sb.Append( encodedValue );
}
else {
sb.Append( c );
}
}
return sb.ToString();
}
static string DecodeEncodedNonAsciiCharacters( string value ) {
return Regex.Replace(
value,
#"\\u(?<Value>[a-zA-Z0-9]{4})",
m => {
return ((char) int.Parse( m.Groups["Value"].Value, NumberStyles.HexNumber )).ToString();
} );
}
}
Outputs:
This function contains a unicode character pi (π)
This function contains a unicode character pi (\u03a0)
This function contains a unicode character pi (π)
For Unescape You can simply use this functions:
System.Text.RegularExpressions.Regex.Unescape(string)
System.Uri.UnescapeDataString(string)
I suggest using this method (It works better with UTF-8):
UnescapeDataString(string)
string StringFold(string input, Func<char, string> proc)
{
return string.Concat(input.Select(proc).ToArray());
}
string FoldProc(char input)
{
if (input >= 128)
{
return string.Format(#"\u{0:x4}", (int)input);
}
return input.ToString();
}
string EscapeToAscii(string input)
{
return StringFold(input, FoldProc);
}
As a one-liner:
var result = Regex.Replace(input, #"[^\x00-\x7F]", c =>
string.Format(#"\u{0:x4}", (int)c.Value[0]));
class Program
{
static void Main(string[] args)
{
char[] originalString = "This string contains the unicode character Pi(π)".ToCharArray();
StringBuilder asAscii = new StringBuilder(); // store final ascii string and Unicode points
foreach (char c in originalString)
{
// test if char is ascii, otherwise convert to Unicode Code Point
int cint = Convert.ToInt32(c);
if (cint <= 127 && cint >= 0)
asAscii.Append(c);
else
asAscii.Append(String.Format("\\u{0:x4} ", cint).Trim());
}
Console.WriteLine("Final string: {0}", asAscii);
Console.ReadKey();
}
}
All non-ASCII chars are converted to their Unicode Code Point representation and appended to the final string.
Here is my current implementation:
public static class UnicodeStringExtensions
{
public static string EncodeNonAsciiCharacters(this string value) {
var bytes = Encoding.Unicode.GetBytes(value);
var sb = StringBuilderCache.Acquire(value.Length);
bool encodedsomething = false;
for (int i = 0; i < bytes.Length; i += 2) {
var c = BitConverter.ToUInt16(bytes, i);
if ((c >= 0x20 && c <= 0x7f) || c == 0x0A || c == 0x0D) {
sb.Append((char) c);
} else {
sb.Append($"\\u{c:x4}");
encodedsomething = true;
}
}
if (!encodedsomething) {
StringBuilderCache.Release(sb);
return value;
}
return StringBuilderCache.GetStringAndRelease(sb);
}
public static string DecodeEncodedNonAsciiCharacters(this string value)
=> Regex.Replace(value,/*language=regexp*/#"(?:\\u[a-fA-F0-9]{4})+", Decode);
static readonly string[] Splitsequence = new [] { "\\u" };
private static string Decode(Match m) {
var bytes = m.Value.Split(Splitsequence, StringSplitOptions.RemoveEmptyEntries)
.Select(s => ushort.Parse(s, NumberStyles.HexNumber)).SelectMany(BitConverter.GetBytes).ToArray();
return Encoding.Unicode.GetString(bytes);
}
}
This passes a test:
public void TestBigUnicode() {
var s = "\U00020000";
var encoded = s.EncodeNonAsciiCharacters();
var decoded = encoded.DecodeEncodedNonAsciiCharacters();
Assert.Equals(s, decoded);
}
with the encoded value: "\ud840\udc00"
This implementation makes use of a StringBuilderCache (reference source link)
A small patch to #Adam Sills's answer which solves FormatException on cases where the input string like "c:\u00ab\otherdirectory\" plus RegexOptions.Compiled makes the Regex compilation much faster:
private static Regex DECODING_REGEX = new Regex(#"\\u(?<Value>[a-fA-F0-9]{4})", RegexOptions.Compiled);
private const string PLACEHOLDER = #"#!#";
public static string DecodeEncodedNonAsciiCharacters(this string value)
{
return DECODING_REGEX.Replace(
value.Replace(#"\\", PLACEHOLDER),
m => {
return ((char)int.Parse(m.Groups["Value"].Value, NumberStyles.HexNumber)).ToString(); })
.Replace(PLACEHOLDER, #"\\");
}
To store actual Unicode codepoints, you have to first decode the String's UTF-16 codeunits to UTF-32 codeunits (which are currently the same as the Unicode codepoints). Use System.Text.Encoding.UTF32.GetBytes() for that, and then write the resulting bytes to the StringBuilder as needed,i.e.
static void Main(string[] args)
{
String originalString = "This string contains the unicode character Pi(π)";
Byte[] bytes = Encoding.UTF32.GetBytes(originalString);
StringBuilder asAscii = new StringBuilder();
for (int idx = 0; idx < bytes.Length; idx += 4)
{
uint codepoint = BitConverter.ToUInt32(bytes, idx);
if (codepoint <= 127)
asAscii.Append(Convert.ToChar(codepoint));
else
asAscii.AppendFormat("\\u{0:x4}", codepoint);
}
Console.WriteLine("Final string: {0}", asAscii);
Console.ReadKey();
}
You need to use the Convert() method in the Encoding class:
Create an Encoding object that represents ASCII encoding
Create an Encoding object that represents Unicode encoding
Call Encoding.Convert() with the source encoding, the destination encoding, and the string to be encoded
There is an example here:
using System;
using System.Text;
namespace ConvertExample
{
class ConvertExampleClass
{
static void Main()
{
string unicodeString = "This string contains the unicode character Pi(\u03a0)";
// Create two different encodings.
Encoding ascii = Encoding.ASCII;
Encoding unicode = Encoding.Unicode;
// Convert the string into a byte[].
byte[] unicodeBytes = unicode.GetBytes(unicodeString);
// Perform the conversion from one encoding to the other.
byte[] asciiBytes = Encoding.Convert(unicode, ascii, unicodeBytes);
// Convert the new byte[] into a char[] and then into a string.
// This is a slightly different approach to converting to illustrate
// the use of GetCharCount/GetChars.
char[] asciiChars = new char[ascii.GetCharCount(asciiBytes, 0, asciiBytes.Length)];
ascii.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0);
string asciiString = new string(asciiChars);
// Display the strings created before and after the conversion.
Console.WriteLine("Original string: {0}", unicodeString);
Console.WriteLine("Ascii converted string: {0}", asciiString);
}
}
}