Java Character.MATH_SYMBOL to C# conversion - c#

.NET 4.6.1 C#
I found a possible solution to a problem I'm having. The solution is written in Java. I converted 99% of it to C# easily, sans 1 line. Here's the synopsis.
They have a string that is converted to a character array. Here's the C# equivalent:
string pFormula = "my string";
char[] tokens = pFormula.ToCharArray();
Then the following line of code occurs (this is Java):
if (Character.getType(tokens[i]) == Character.MATH_SYMBOL){
//do something
}
This is where i'm stuck. I can do this:
tokens[i].GetType() //Character.getType(tokens[i])
Does anyone know the C# equivalent of java's Character.MATH_SYMBOL? Thanks

char plus = '+';
if(char.GetUnicodeCategory(plus) == UnicodeCategory.MathSymbol)
{
//return true
}
You need to use UnicodeCategory
Be aware not every symbol which can be used in Math is in UnicodeCategory.MathSymbol. * and / are not part of MathSybols
char a2 = '*';
if(char.GetUnicodeCategory(a2) == UnicodeCategory.OtherPunctuation)
{
//return true, but return false for Math.
}
Here how it looks like the unicode character for multiplication and division used in MathSymbols.
char multiplication = '×';
char division = '÷';
Here this should be List of characters in unicode designation Sm(symbol,math)

Related

C# - Is there no simple way to concatenate hex and ASCII into a single string

In Python I'm able to concatenate both hex and ascii into a single string, then send it to the device I'm trying to control
_startTransmit = "\x02"
_channel = 7
command_string = _startTransmit + "PGM:" + str(_channel) + ";"
try:
written = conn.write(command_string.encode('utf-8'))
This SO Answer makes it appear building a byte array is the only way to do it in C#
So, it appears there is no similar way to concatenate hex and ascii in C# as there is in Python. Am I correct?
I'd look at using the string interpolator operator $ before the "string":
var _startTransmit = (char)0x02; //ints can be written in 0xFF format in the source code and cast to char e.g. (char)0x41 is a capital A
var _channel = 7;
var command_string = $"{_startTransmit}PGM:{_channel};"
The last line is syntactic sugar for:
var command_string = string.Format("{0}PGM:{1};", _startTransmit, _channel);
The things in {brackets} can have format specifiers, eg pad out the _channel to 4 chars with leading spaces, zeroes etc {_channel:0000} - see https://learn.microsoft.com/en-us/dotnet/api/system.string.format?view=netframework-4.8

Converting unicode characters (C#) Testing

I have the following problem
I am using an SDK that returns values form a database.
The value i need is 4, 6, 7 but the SDK returns "\u0004","\u0006","\u0007" I was wondering if there is a way to check if it is "\u0004","\u0006","\u0007" or any way of doing this?
I Have the following code (C#):
Line_Type = Line_Type.Replace(#"\u000", "");
if (Line_Type == "4")
{
Line_Type = "4";
}
else if (Line_Type == "6")
{
Line_Type = "6";
}
else if (Line_Type == "7")
{
Line_Type = "7";
}
I have tried multiple ways to get the done but can't find a right way to get this done.
I Have google but can't find anything.
From your question I understood that SDK returns values in unicoded style.
Then you can use the following code to convert unicode values to respective decimal value.
char uniCodeValue = char.Parse(Line_Type);// '\u0004' unicode values
int decimalValue = uniCodeValue;
Console.Write(decimalValue.ToString()); // prints 4
Hope your problem got solved!!
In your replace call, "\u" is considered as an escape char. if you use double \, you get the string "\u0009";
check the difference between these two:
Console.WriteLine ("\u0009");
Console.WriteLine ("\\u0009");
the second print the string you are trying to replace with an empty string.

Convert Unicode string made up of culture-specific digits to integer value

I am developing a program in the Marathi language. In it, I want to add/validate numbers entered in Marathi Unicode by getting their actual integer value.
For example, in Marathi:
४५ = 45
९९ = 99
How do I convert this Marathi string "४५" to its actual integer value i.e. 45?
I googled a lot, but found nothing useful. I tried using System.Text.Encoding.Unicode.GetString() to get string and then tried to parse, but failed here also.
Correct way would be to use Char.GetNumericValue that lets you to convert individual characters to corresponding numeric values and than construct complete value. I.e. Char.GetNumericValue('९') gives you 9.
Depending on your goal it may be easier to replace each national digit character with corresponding invariant digit and use regular parsing functions.
Int32.Parse("९९".Replace("९", "9"))
Quick hack of #Alexi's response.
public static double ParseValue(string value)
{
return double.Parse(string.Join("",
value.Select(c => "+-.".Contains(c)
? "" + c: "" + char.GetNumericValue(c)).ToArray()),
NumberFormatInfo.InvariantInfo);
}
calling ParseValue("१२३.३२१") yields 123.321 as result
I found my solution...
The following code will convert given Marathi number to its equivalent Latin number..
Thanks to #Alexei, I just changed some of your code and its working fine..
string ToLatinDigits(string nativeDigits)
{
int n = nativeDigits.Length;
StringBuilder latinDigits = new StringBuilder(capacity: n);
for (int i = 0; i < n; ++i)
{
if (char.IsDigit(nativeDigits, i))
{
latinDigits.Append(char.GetNumericValue(nativeDigits, i));
}
else if (nativeDigits[i].Equals('.') || nativeDigits[i].Equals('+') || nativeDigits[i].Equals('-'))
{
latinDigits.Append(nativeDigits[i]);
}
else
{
throw new Exception("Invalid Argument");
}
}
return latinDigits.ToString();
}
This method is working for both + and - numbers.
Regards Guruprasad
Windows.Globalization.DecimalFormatter will parse different numeral systems in addition to Latin, including Devanagari (which is what is used by Marathi).

the equivalent of sscanf_s in C#?

UnlockOffset is DWORD. thisKey is a char[5]
if(EOF == sscanf_s(thisKey, "%d", &UnlockOffset))
How would the above code be done in c# ?
DWORD was converted to UInt32 and thiskey remained char array but I still dont understand the sscanf_s.
PS: I did check MSDN but was not able to understand it very well which was why I posted it here.
sscanf_s basically reads a string and extracts stuff that matches the format string. It'll return EOF if it couldn't extract stuff to match all the format thingies.
You could do something like
string str = new string(thisKey);
if (!UInt32.TryParse(str, out UnlockOffset))
which would accomplish something similar, but it might be more or less strict. UInt32.TryParse returns true if it could convert the string and false if it couldn't, so checking for EOF would be equivalent to seeing whether TryParse is false.
Typically, you would use UInt32.Parse (or TryParse) to pull the information out of a string. It is rare that char[] is used to store string values in C#, as string is more appropriate.
Since everyone has already mentioned uint.Parse (and uint.TryParse), you can convert your char array to an integer like this:
uint UnlockOffset = 0;
foreach (char digit in thisKey)
{
UnlockOffset *= 10;
UnlockOffset += (uint)(digit - '0');
}
If thisKey is "123 456 739" then sscanf_s(thisKey, "%d", &UnlockOffset)) would get 123 into UnlockOffset
Here's an approximate equivalent
string str = new string(thisKey);
string[] strAr = str.Split(' ');
UnlockOffset = Convert.ToUInt32(strAr!=null ? strAr[0] : str);

SHA1 C# method equivalent in Perl?

I was given C# code and I'm trying to generate the equivalent SHA1 using Perl.
public string GetHashedPassword(string passkey)
{
// Add a timestamp to the passkey and encrypt it using SHA1.
string passkey = passkey + DateTime.UtcNow.ToString("yyyyMMddHH0000");
using (SHA1 sha1 = new SHA1CryptoServiceProvider())
{
byte[] hashedPasskey =
sha1.ComputeHash(Encoding.UTF8.GetBytes(passkey));
return ConvertToHex(hashedPasskey);
}
}
private string ConvertToHex(byte[] bytes)
{
StringBuilder hex = new StringBuilder();
foreach (byte b in bytes)
{
if (b < 16)
{
hex.AppendFormat("0{0:X}", b);
}
else
{
hex.AppendFormat("{0:X}", b);
}
}
return hex.ToString();
}
The same as:
use Digest::SHA1 qw( sha1_hex );
my $pass = "blahblah";
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime();
$year += 1900;
my $date = sprintf("%d%02d%02d%02d0000", $year, $mon+1, $mday, $hour);
my $passSha1 = sha1_hex($pass.$date);
//9c55409372610f8fb3695d1c7c2e6945164a2578
I don't actually have any C# experience so I'm not able to test what is normally outputted from the C# code.
The code is supposed to be used as a checksum for a website but the one I'm providing is failing.
Edit: it also adds the UTC timestamp (yyyyMMDDHH0000) to the end of the pass before hashing so I've added that code in case the issue is there.
I do not know C# either. However, {0:X} formats hex digits using upper case letters. So, would
my $passSha1 = uc sha1_hex($pass);
help? (Assuming GetHashedPassword makes sense.)
The only difference I can see (from running the code under Visual Studio 2008) is that the C# code is returning the hex string with alphas in uppercase
D3395867D05CC4C27F013D6E6F48D644E96D8241
and the perl code is using lower case for alphas
d3395867d05cc4c27f013d6e6f48d644e96d8241
The format string used in the C# code is asking for uppercase ("X" as opposed to "x"):
hex.AppendFormat("{0:X}", b);
Maybe the code at the website is using a case sensitive comparison? I assume it would be trivial for you to convert the output from the CPAN function to uppercase before you submit it?
Could it be as simple as changing the uppercase 'X' in the AppendFormat call to a lowercase 'x'?
I think you're looking for Digest::SHA1
Your SHA-1 could have also just been:
BitConverter.ToString(SHA.ComputeHash(buffer)).Replace("-", "");

Categories

Resources