I need to decode GSM 7 bit to ascii string in c# so that I googled and found lots of different posts about it, this post is one of them but It is not a c#.
Can anyone please share a c# code that can decode GSM 7-bit Character to ASCII string.
Thanks.
class GSM7BitDecoder
{
// Basic Character Set
private const string BASIC_SET =
"#£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\x1bÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>?" +
"¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà";
// Basic Character Set Extension
private const string EXTENSION_SET =
"````````````````````^```````````````````{}`````\\````````````[~]`" +
"|````````````````````````````````````€``````````````````````````";
string[] BASIC_SET_ARRAY = BASIC_SET.Select(x => x.ToString()).ToArray();
string[] EXTENSION_SET_ARRAY = EXTENSION_SET.Select(x => x.ToString()).ToArray();
enum circle { Start=1, Complete=8 }
string GetChar(string bin)
{
try
{
if (Convert.ToInt32(bin, 2).Equals(27))
return EXTENSION_SET_ARRAY[Convert.ToInt32(bin, 2)];
else
return BASIC_SET_ARRAY[Convert.ToInt32(bin, 2)];
}
catch { return string.Empty; }
}
public string DecodeGSM7bit(string strGsm7bit)
{
var suffix = string.Empty;
var septet = string.Empty;
var CurSubstr = string.Empty;
var counter = 1;
List<string> septets = new List<string>();
List<string> sectets = new List<string>();
//Prepare Octets
var octets = Enumerable.Range(0, strGsm7bit.Length / 2).Select(i =>
{
return Convert.ToString(Convert.ToInt64(strGsm7bit.Substring(i * 2, 2), 16), 2).PadLeft(8,'0');
}).ToList();
for (var index=0; index < octets.Count; index = index +1)
{
//Generate Septets
septet = octets[index].Substring(counter);
CurSubstr = octets[index].Substring(0, counter);
if (counter.Equals((int)circle.Start))
septets.Add(septet);
else
septets.Add(septet + suffix);
//Organize Sectets
sectets.Add(GetChar(septets[index]));
suffix = CurSubstr;
counter++;
//Reset counter when the circle is complete.
if (counter == (int)circle.Complete)
{
counter = (int)circle.Start;
sectets.Add(GetChar(suffix));
}
}
return string.Join("", sectets);
}
Related
I need some help with JS code translation to C#.
JS Code:
function Decription(string) {
var newString = '',
char, codeStr, firstCharCode, lastCharCode;
var ft = escape(string);
string = decodeURIComponent(ft);
for (var i = 0; i < string.length; i++) {
char = string.charCodeAt(i);
if (char > 132) {
codeStr = char.toString(10);
firstCharCode = parseInt(codeStr.substring(0, codeStr.length - 2), 10);
lastCharCode = parseInt(codeStr.substring(codeStr.length - 2, codeStr.length), 10) + 31;
newString += String.fromCharCode(firstCharCode) + String.fromCharCode(lastCharCode);
} else {
newString += string.charAt(i);
}
}
return newString;
}
And I tied to translate on C#:
private string Decription(string encriptedText)
{
string ft = Regex.Escape(encriptedText);
string text = HttpUtility.UrlDecode(ft);
string newString = "";
for (int i = 0; i < text.Length; i++)
{
var ch = (int)text[i];
if(ch > 132)
{
var codeStr = Convert.ToString(ch, 10);
var firstCharCode = Convert.ToInt32(codeStr.Substring(0, codeStr.Length - 2), 10);
var lastCharCode = Convert.ToInt32(codeStr.Substring(codeStr.Length - 2, codeStr.Length), 10) + 31;
}
}
}
But how I can translate this row:
newString += String.fromCharCode(firstCharCode) + String.fromCharCode(lastCharCode);
Maybe do you know equivalent method to String.fromCharCode() on C# ?
Here you go:
public static void Main()
{
// from 97 to a
int i = 97;
Console.WriteLine(StringFromCharCode(97));
}
public static string StringFromCharCode(int code) => ((char)code).ToString();
Demo
Note that you may want to use a StringBuilder instead of concatening string in your case.
Related to Int to Char in C# (Read it. It includes a nice comment about cast vs Convert.ToChar)
You can simply use Convert.ToChar method, Convert.ToChar(97) will return a.
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;
}
Please bear with me, I'm very confused and I may be making completely no sense. I play a game which I have a source to that is coded in c#, and I'm trying to make a command that I use in game, that which plays a sound.
I've got this:
string[] Strings = new string[2];
Strings[0] = "sound/1.mp3";
Strings[1] = "1";
SendPacket(General.MyPackets.String(MyChar.UID, 20, Strings));
On the Strings in the SendPacket, it says it cannot convert string[] string.
I know I'm doing this wrong, and in an example I've seen someone else do, it contained a "split(' ')", but I'm not sure how to do it.
Here is that example I saw (THIS IS NOT MY CODE, BUT A REFERENCE I TRIED TO USE AND FAILED)
{
string[] Strings = new string[2];
string[] sound = param.Split(' ');
Strings[0] = sound[1];
Strings[1] = "1";
string todo = sound[0];
string media = sound[1];
if (todo == "play")
{
CSocket.Send(CoPacket.String(Strings, 0, (Struct.StringType)(20), 2));
}
else if (todo == "broadcast")
{
foreach (ClientSocket CS in World.ClientPool.Values)
{
CSocket.Send(CoPacket.String(Strings, 0, (Struct.StringType)(20), 2));
}
}
break;
}
I'm wanting to know how to make my code work, but sending strings(1 and 2). Thanks for any help, and I'm very sorry if I've confused you.
public void SendPacket(byte[] Dat)
{
try
{
if (ListenSock != null)
if (ListenSock.WinSock.Connected)
{
int Len = Dat[0] + (Dat[1] << 8);
if (Dat.Length != Len)
return;
System.Threading.Monitor.TryEnter(this, new TimeSpan(0, 0, 0, 8, 0));
byte[] Data = new byte[Dat.Length];
Dat.CopyTo(Data, 0);
Crypto.Encrypt(ref Data);
ListenSock.WinSock.Send(Data);
System.Threading.Monitor.Exit(this);
}
}
catch { }
}
public byte[] String(long CharId, byte Type, string name)
{
ushort PacketType = 1015;
byte[] Packet = new byte[13 + name.Length];
fixed (byte* p = Packet)
{
*((ushort*)p) = (ushort)Packet.Length;
*((ushort*)(p + 2)) = (ushort)PacketType;
*((uint*)(p + 4)) = (uint)CharId;
*(p + 8) = Type;
*(p + 9) = 1;
*(p + 10) = (byte)name.Length;
for (int i = 0; i < name.Length; i++)
{
*(p + 11 + i) = Convert.ToByte(name[i]);
}
}
return Packet;
}
Try this one
string[] Strings = new string[2];
Strings[0] = "sound/1.mp3";
Strings[1] = "1";
SendPacket(General.MyPackets.String(MyChar.UID, 20, String.Join(' ', Strings)));
try this:
string[] Strings = new string[2];
string[] sound = param.Split(' ');
Strings[0] = sound[1];
Strings[1] = "1";
string todo = sound[0];
string media = sound[1];
string concatString = Strings[0] + Strings[1];
if (todo == "play")
{
CSocket.Send(CoPacket.String(concatString , 0, (Struct.StringType)(20), 2));
}
Your error:
cannot convert string[] in string
just means that you are trying to convert an array/list of type "string" into a single string, but C# is unable to do this by default so you have to do it yourself.
Now to your code example:
He is using a different method from you. He used String(string[] ?? , ??, ??, ??) and you String(long CharId, byte Type, string name)
This is based on the assumption that his CoPacket and your MyPackets are the same class.
How can I convert a string to correct GSM encoded value to be sent to a mobile operator?
Below is a port of gnibbler's answer, slightly modified and with a detailed explantation.
Example:
string output = GSMConverter.StringToGSMHexString("Hello World");
// output = "48-65-6C-6C-6F-20-57-6F-72-6C-64"
Implementation:
// Data/info taken from http://en.wikipedia.org/wiki/GSM_03.38
public static class GSMConverter
{
// The index of the character in the string represents the index
// of the character in the respective character set
// Basic Character Set
private const string BASIC_SET =
"#£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\x1bÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>?" +
"¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà";
// Basic Character Set Extension
private const string EXTENSION_SET =
"````````````````````^```````````````````{}`````\\````````````[~]`" +
"|````````````````````````````````````€``````````````````````````";
// If the character is in the extension set, it must be preceded
// with an 'ESC' character whose index is '27' in the Basic Character Set
private const int ESC_INDEX = 27;
public static string StringToGSMHexString(string text, bool delimitWithDash = true)
{
// Replace \r\n with \r to reduce character count
text = text.Replace(Environment.NewLine, "\r");
// Use this list to store the index of the character in
// the basic/extension character sets
var indicies = new List<int>();
foreach (var c in text)
{
int index = BASIC_SET.IndexOf(c);
if(index != -1) {
indicies.Add(index);
continue;
}
index = EXTENSION_SET.IndexOf(c);
if(index != -1) {
// Add the 'ESC' character index before adding
// the extension character index
indicies.Add(ESC_INDEX);
indicies.Add(index);
continue;
}
}
// Convert indicies to 2-digit hex
var hex = indicies.Select(i => i.ToString("X2")).ToArray();
string delimiter = delimitWithDash ? "-" : "";
// Delimit output
string delimited = string.Join(delimiter, hex);
return delimited;
}
}
The code of Omar Didn't work for me. But I found The actual code that works:
public static string Encode7bit(string s)
{
string empty = string.Empty;
for (int index = s.Length - 1; index >= 0; --index)
empty += Convert.ToString((byte)s[index], 2).PadLeft(8, '0').Substring(1);
string str1 = empty.PadLeft((int)Math.Ceiling((Decimal)empty.Length / new Decimal(8)) * 8, '0');
List<byte> byteList = new List<byte>();
while (str1 != string.Empty)
{
string str2 = str1.Substring(0, str1.Length > 7 ? 8 : str1.Length).PadRight(8, '0');
str1 = str1.Length > 7 ? str1.Substring(8) : string.Empty;
byteList.Add(Convert.ToByte(str2, 2));
}
byteList.Reverse();
var messageBytes = byteList.ToArray();
var encodedData = "";
foreach (byte b in messageBytes)
{
encodedData += Convert.ToString(b, 16).PadLeft(2, '0');
}
return encodedData.ToUpper();
}