I want to add a text box where a user can input a number. No matter how large or small the number, it needs to be stored as a double. Then with a click button, the hex equivalent will be displayed in a second text box. Bonus points if you can show me how to take the 16 byte hex and change it to 4 variables with 4 bytes each.
For example, user enters 1234.56 in textbox1. Clicks button 1, and textbox2 displays the hex equivilent "40934A3D70A3D70A" Then take that string, and extract to 4 different 4-byte strings so str1=1093, str2=4A3D, str3=70a3, str4=d70A.
Are you looking for BitConverter? C# implementation:
double source = 1234.56;
// 40934A3D70A3D70A
string result = string.Concat(BitConverter
.GetBytes(source)
.Reverse()
.Select(b => b.ToString("X2")));
Having got result, extract its parts with Substring:
string str1 = result.Substring(0, 4);
string str2 = result.Substring(4, 4);
string str3 = result.Substring(8, 4);
string str4 = result.Substring(12, 4);
If you are looking for a C# implementation, try this:
static void Main(string[] args)
{
var number = 1234.56;
string hex = DoubleToHex(number);
string part1 = hex.Substring(0, 4);
string part2 = hex.Substring(4, 4);
string part3 = hex.Substring(8, 4);
string part4 = hex.Substring(12, 4);
}
internal static string DoubleToHex(double value)
{
var b = BitConverter.GetBytes(value).Reverse();
string result = string.Join(string.Empty, b.Select(i => i.ToString("X2")).ToArray());
return result;
}
This is the most efficient answer you're going to get:
unsafe static void Main()
{
var value = 1234.56;
var pLong = (long*)&value;
var fullString = (*pLong).ToString("X");
var pShort = (short*)pLong;
short value0 = *pShort, value1 = *(pShort + 1), value2 = *(pShort + 2),
value3 = *(pShort + 3);
string s0 = value0.ToString("X"), s1 = value1.ToString("X"), s2 = value2.ToString("X"),
s3 = value3.ToString("X");
Debug.Print(fullString);
Debug.Print(s0);
Debug.Print(s1);
Debug.Print(s2);
Debug.Print(s3);
}
Output:
40934A3D70A3D70A
D70A
70A3
4A3D
4093
Translation of Dmitry Bychenko answer to VB.NET:
Imports SplitValue = System.Tuple(Of String, String, String, String)
Module Module1
Function DoubleToByteArray(ByVal AValue As Double) As Byte()
Return BitConverter.GetBytes(AValue).Reverse().ToArray()
End Function
Function SplitByteArray(ByRef AValue As Byte()) As SplitValue
Dim StringValue As String = String.Join("", From AByte In AValue Select AByte.ToString("X2"))
Return New SplitValue(StringValue.Substring(0, 4), StringValue.Substring(4, 4), StringValue.Substring(8, 4), StringValue.Substring(12, 4))
End Function
Sub Main()
Dim Result As SplitValue
Result = SplitByteArray(DoubleToByteArray(1234.56))
Console.WriteLine(Result)
Console.ReadLine()
End Sub
End Module
Output:
(4093, 4A3D, 70A3, D70A)
try it: DoubleToHex
//dashseparator 0 /2/4
public string DoubleToHex(double d, bool reverse = false, int dashSeparator = 0)
{
byte[] bytes = BitConverter.GetBytes(d);
if (reverse) bytes = bytes.Reverse().ToArray();
var hex = BitConverter.ToString(bytes);
var hex4 = "";
if (dashSeparator == 2) return hex;
if (dashSeparator == 4)
{
hex = hex.Replace("-", "");
hex = Regex.Replace(hex, ".{4}", "$0-").TrimEnd('-');
return hex;
}
return hex.Replace("-", "");
}
sample Output:
Double: 1234.56
Hex: 0AD7A3703D4A9340
Hex in Reverse order: 40934A3D70A3D70A
Hex in Reverse order separate by 2 digits: 40-93-4A-3D-70-A3-D7-0A
Hex in Reverse order separate by 4 digits: 4093-4A3D-70A3-D70A
you can :
-control the generated Hex to be displayed in order/ reverse order.
-Add dash separator by 0 (no separator) / 2 /4 digits
Edit:
Vb.Net Version
Converting Code to Vb.Net
'dashseparator 0 /2/4
Public Function DoubleToHex(d As Double, Optional reverse As Boolean = False, Optional dashseparator As Integer = 0) As String
Dim bytes As Byte() = BitConverter.GetBytes(d)
If reverse Then
Array.Reverse(bytes)
End If
Dim hex = BitConverter.ToString(bytes)
Dim hex4 = ""
If dashseparator = 2 Then
Return hex
End If
If dashseparator = 4 Then
hex = hex.Replace("-", "")
hex = Regex.Replace(hex, ".{4}", "$0-").TrimEnd("-"C)
Return hex
End If
Return hex.Replace("-", "")
End Function
Related
I have a textbox which i need to validate for the below entries and also need to replace
"3 GB" valid input
"3.2 GB" valid input
"3.2GB" valid input >> then replace as "3.2 GB"
"3.2" invalid input, ask for follow correct format MsgBox("follow the format like: 1 TB or 1.1 TB, 1 GB, 10 MB")
"VGGGB" invalid input, ask for follow correct format MsgBox("follow the format like: 1 TB or 1.1 TB, 1 GB, 10 MB")
Sub Main()
Dim input = Console.ReadLine().ToUpper()
Dim nInput, value
Dim ChkDecimal As Double
If input IsNot "" Then
If input.EndsWith("TB") Then
nInput = input.Replace("TB", "")
If nInput IsNot vbNullString And IsNumeric(nInput) Then
value = Convert.ToDouble(nInput)
value = CDbl(value * 1048576 + 1)
ChkDecimal = FormatNumber(CDbl(value / 1048576), 2) Mod 1 ' check the number has a valid Decimal value
If ChkDecimal = 0 Then
Console.WriteLine(FormatNumber(CDbl(value / 1048576), 0) & " TB")
Else
Console.WriteLine(FormatNumber(CDbl(value / 1048576), 2) & " TB")
End If
Else
Console.WriteLine("Invalid format!! should like: 99.99 MB/GB/TB")
End If
ElseIf (input.EndsWith("GB")) Then
nInput = input.Replace("GB", "")
If nInput IsNot vbNullString And IsNumeric(nInput) Then
value = Convert.ToDouble(nInput)
value = CDbl(value * 1024)
ChkDecimal = FormatNumber(CDbl(value / 1024), 2) Mod 1 ' check the number has a valid Decimal value
If ChkDecimal = 0 Then
Console.WriteLine(FormatNumber(CDbl(value / 1024), 0) & " GB")
Else
Console.WriteLine(FormatNumber(CDbl(value / 1024), 2) & " GB")
End If
Else
Console.WriteLine("Invalid format!! should like: 99.99 MB/GB/TB")
End If
ElseIf input.EndsWith("MB") = True Then
nInput = input.Replace("MB", "")
If nInput IsNot vbNullString And IsNumeric(nInput) Then
value = Convert.ToDouble(nInput)
value = CDbl(value * 1)
Console.WriteLine(FormatNumber(CDbl(value * 1), 0) & " MB")
Else
Console.WriteLine("Invalid format!! should like: 99.99 MB/GB/TB")
End If
Else
Console.WriteLine("Invalid format!! should like: 99.99 MB/GB/TB")
End If
Else
Console.WriteLine("Capacity input Format: 99.99 MB/GB/TB")
End If
End Sub
I wouldn't use a regular-expression for this, because there's a much simpler (and more robust!) approach described below.
If you do use a regular-expression, you'll need to add all of the unit names to the expression, which is painful. Regular-expressions are not well-suited to accepting a large list of possible literal inputs.
Using a regular-expression would also mean the input would not be culture-aware, which is bad for usability (as many places around the world swap the , and . glyphs in numbers) - and you really don't want to handle things like digit-grouping, etc.
Instead, first extract and validate the unit name, then parse the numeric value using Decimal.TryParse
Like so (using C# because it's 2am here and I'm not getting paid to write this answer):
void Example()
{
String textBoxValue = "3 GB";
if( TryParseBinaryDataQuantity( textBoxValue, out Int64 valueBytes ) )
{
MessageBox.Show( "Visual Basic is dead." );
}
else
{
MessageBox.Show( "Input is not a valid binary data quantity." );
}
}
public static Boolean TryParseBinaryDataQuantity( String input, out Int64 valueBytes )
{
input = ( input ?? "" ).Trim();
if( input.Length < 3 ) // input is too short to be meaningful.
{
valueBytes = default;
return false;
}
// Extract the unit-name by taking the last 3 characters of the input string and trimming any whitespace (this isn't the most robust or correct approach, but I'm feeling lazy):
String unitName = input.Substring( startIndex: input.Length - 3 );
// Validate the unit-name and get the bytes multiplier:
if( !TryParseBinaryDataUnit( unitName, out Int64 multiplier ) )
{
valueBytes = default;
return false;
}
// Consider repeating the above but for the last 2 characters of the string in order to match input like "3GB" instead of "3GiB" and "3 GB" and "3 GiB".
// Parse and multiply:
String numberPart = input.Substring( startIndex: 0, length: input.Length - 3 );
if( Decimal.TryParse( numberPart, NumberStyles.Any, CultureInfo.CurrentCulture, out Decimal quantity )
{
Decimal bytesValue = quantity * multiplier;
// Fail if the bytesValue is non-integral or negative:
if( bytesValue != Math.Floor( bytesValue ) || bytesValue < 0 )
{
valueBytes = default;
return false;
}
return (Int64)bytesValue;
}
}
private static Boolean TryParseBinaryDataUnit( String unitName, out Int64 equivalentBytes )
{
if( "GB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
{
equivalentBytes = 1024 * 1024 * 1024; // or 1000 * 1000 * 1000 depending on if you're differentiating between GiB and GB.
return true;
}
else if( "GiB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
{
equivalentBytes = 1024 * 1024 * 1024;
return true;
}
else if( "MiB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
{
equivalentBytes = 1024 * 1024;
return true;
}
else if( "MB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
{
equivalentBytes = 1024 * 1024;
return true;
}
else if( "KB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
{
equivalentBytes = 1024;
return true;
}
else if( "KB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
{
equivalentBytes = 1024;
return true;
}
else
{
equivalentBytes = default;
return false;
}
}
I will recommend you to use proper library to parse the given input. I have used one in past for doing this (https://github.com/omar/ByteSize)
Here is quick example of how you can do this. I know there must be better way to do this but this would do the job =)
var input = Console.ReadLine();
input = input.ToLower();
var reg = Regex.Match(input, "([\\d\\.]+)");
if (reg.Success && double.TryParse(reg.Groups[1].Value, out double rawSize))
{
if (input.EndsWith("tb"))
Console.WriteLine(ByteSize.FromTeraBytes(rawSize));
else if (input.EndsWith("gb"))
Console.WriteLine(ByteSize.FromGigaBytes(rawSize));
else if (input.EndsWith("mb"))
Console.WriteLine(ByteSize.FromMegaBytes(rawSize));
else if (input.EndsWith("kb"))
Console.WriteLine(ByteSize.FromKiloBytes(rawSize));
}
Input> 1234.56mb
Output> 1.23 GB
You can try my method as following:
Imports System.Text.RegularExpressions
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'1.3 GB
'1.3gb
'1gb
Console.WriteLine("Pleasen input your entry:")
Dim str As String = TextBox1.Text
Dim str1 As String = str.Substring(str.Length - 2, 2)
If str1.ToUpper = "TB" Or str1.ToUpper = "GB" Or str1.ToUpper = "MB" Then
Dim str2 As String = str.Remove(str.Length - 2)
Dim str3 As String = str.Substring(str2.Length - 1, 1)
If str3 = " " Then
Dim str4 As String = str.Remove(str.Length - 3)
If Regex.IsMatch(str4, "^\d*[.]?\d*$") Then
MsgBox("valid input")
Else
MsgBox("follow the format like: 1 TB or 1.1 TB, 1 GB, 10 MB")
Return
End If
Else
If Regex.IsMatch(str2, "^\d*[.]?\d*$") Then
TextBox1.Text = str.Insert(str.Length - 2, " ")
MsgBox("valid input")
Else
MsgBox("follow the format like: 1 TB or 1.1 TB, 1 GB, 10 MB")
Return
End If
End If
Else
MsgBox("follow the format like: 1 TB or 1.1 TB, 1 GB, 10 MB")
Return
End If
End Sub
End Class
I am working on new decryption functions for password recovery tools. I tried code in c++ and worked:
void poco_pwd(u_char *pwd, int type) {
int len,
tmp;
u_char *out;
short azz;
if(type) azz = 0x2537; // encrypt message
else azz = 0x2a9a; // other passwords
len = strlen(pwd) >> 1;
out = pwd;
while(len--) {
sscanf(pwd, "%02X", &tmp);
pwd += 2;
*out++ = tmp ^ (azz >> 8);
azz = ((tmp + azz) * 0x8141) + 0x3171;
}
*out = 0;
}
I tried to convert this code to vb.net and c# but it throws arithmetic overflow operation. This functions new value is put to "azz" variable. "azz" is a short variable but this these values are very high. Strange is that it works in c++.
I converted this code to vb.net:
Dim encpass As String = "1EF66D8BD3C32476CEC8CF"
Dim encpassByte As Byte() = Encoding.UTF8.GetBytes(HexToString(encpass))
Dim azz As Integer = &H2A9A
Dim len As Integer = encpassByte.Length >> 1
Dim storage(len) As Char
For i = 0 To len
storage(i) = (ChrW(encpassByte(i) Xor (azz >> 8)))
azz = ((encpassByte(i) + azz) * &H8141) + &H3171 //Error: arithmetic operation resulted in an overflow.
Next
Console.WriteLine(storage.ToString)
Console.ReadKey()
Hex to string function:
Function HexToString(ByVal hex As String) As String
Dim text As New System.Text.StringBuilder(hex.Length \ 2)
For i As Integer = 0 To hex.Length - 2 Step 2
text.Append(Chr(Convert.ToByte(hex.Substring(i, 2), 16)))
Next
Return text.ToString
End Function
This code throws this error: arithmetic operation resulted in an overflow.
I would like to convert the string that I've inputted to it's equivalent hex.
For example:
I have the string D7 and I would like it to be converted to hex D7 so that it can be read by the software that can only read hex values.
bla-bla-bla = Error, because there's no hex equivalent of it
aBc = ABC because there's a hex equivalent of it.
123 = 123 because there's a hex equivalent of it.
12 AB 3.14 = Error, because there's no hex equivalent of it
3.F1 = Error, because there's no hex equivalent of it
Though I'm not sure about that, but I guess that will be the result. As long as there's no hex equivalent of each text then it will be error.
Edit: I've tried to convert the C# code of Dmitry, but it is still not working. I'll try it again on Monday
Here's the code
Dim source As String = "abc789Def"
Dim Sb As New StringBuilder(source.Length)
For Each c As Char In source
If ((c >= "0" AndAlso c <= "9") Or (c >= "a" AndAlso c <= "f") Or (c >= "A" AndAlso c <= "F")) Then
Sb.Append(Char.ToUpper(c))
Dim result As String = Sb.ToString
Console.WriteLine("result " & result)
Else
Console.Write("Error")
End If
Next
It seems, that you want to have the string to be in upper case if all the characters in it are in either ['0'..'9'] or ['a'..'f'] or ['A'..'F'] range (C# code):
String source = "abc789Def";
if (source.All(c => (c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F'))) {
String result = source.ToUpper();
//TODO: put a relevant code here
}
else {
// error: at least one character can't be converted
}
Edit: no Linq solution:
String source = "abc789Def";
StringBuilder Sb = new StringBuilder(source.Length);
foreach (Char c in source)
if ((c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F'))
Sb.Append(Char.ToUpper(c));
else {
// Error: at least one character can't be converted
return;
}
String result = Sb.ToString();
// Put relevant code here
The ability to validate a Hex number is provided by the TryParse method on integer types using the System.Globalization.NumberStyles.HexNumber style.
Dim inputValue As String = "23"
Dim returnValue As String = Nothing
If ValidateAndFormatHex(inputValue, returnValue) Then
Console.WriteLine(returnValue)
Else
Console.WriteLine("Error")
End If
Private Shared Function ValidateAndFormatHex(input As String, ByRef formattedValue As String) As Boolean
input = input.Trim().ToUpperInvariant
Dim result As Int32
Dim parses As Boolean = Int32.TryParse(input, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, result)
If parses Then formattedValue = input
Return parses
End Function
I want to try that if they input only two characters in the first name, it will also display, because only three characters and up is readable. thanks
String first = "";
String lnm = "";
String num = "";
String stud = "";
int num1;
int num2;
int id;
String fname = request.getParameter("name");
String lname = request.getParameter("last");
String Sid = request.getParameter("num");
first = fname.substring(fname.length()-3);
lnm = lname.substring(0, 3);
num1 = Integer.parseInt(Sid.substring(0, 2));
num2 = Integer.parseInt(Sid.substring(Sid.length()-6));
id = num2/num1;
stud = Integer.toString(id);
out.println(first + lnm + stud.substring(0, 4));
I found the following link which has a solution to a similar problem and I think it will solve your problem as well: How to get the last characters in a String in Java, regardless of String size
Jon Skeet responded to that post with 3 different possible solutions. His second solution should solve your problem as well:
String numbers = text.substring(Math.max(0, text.length() - 7));
In your case this would be:
first=fname.substring(Math.max(0, fname.length()-3));
I hope that helps.
How would I go on splitting a string into pairs of letter in VB?
for example: abcdefgh
split into: ab cd ef gh
I'll throw my hat in the ring:
Dim test As String = "abcdefgh"
Dim results As New List(Of String)
For i As Integer = 0 To test.Length - 1 Step 2
If i + 1 < test.Length Then
results.Add(test.Substring(i, 2))
Else
results.Add(test.Substring(i))
End If
Next
MessageBox.Show(String.Join(" ", results.ToArray))
The following allows for odd length strings. If the string is zero-length, I'm not sure what you'd want to do, you'll want to address that case.
Dim src As String = "abcdef"
Dim size As Integer
If src.Length > 0 Then
If src.Length Mod 2 = 0 Then
size = (src.Length / 2) - 1
Else
size = ((src.Length + 1) / 2) - 1
End If
Dim result(size) As String
For i = 0 To src.Length - 1 Step 2
If i = src.Length - 1 Then
result(i / 2) = src.Substring(i, 1)
Else
result(i / 2) = src.Substring(i, 2)
End If
Next
End If
In C# you would do like this:
Dictionary<String, String> Split(String input)
{
if (input.Count % 2 == 0)
{
Dictionary<string, string> Pairs = new Dictionary( );
for (int L = 0, R = 1; L < input.Count && R <= input.Count; ++L, ++R)
{
Char
Left = input[L],
Right = input[R];
Pairs.Add(
Left.ToString(),
Right.ToString());
}
}
else
{
throw new NotEvenException( );
}
return Pairs( );
}
void Main()
{
var Pairs = Split("ABCDEFGH");
foreach(string Key in Split("ABCDEFGH"))
{
Console.Write("{0}{1}\n", Key, Pairs[Key]);
}
}
/*
Output:
AB
CD
EF
GH
*/
Now, I know what you think: This isn't what I want! But I say: It is actually, at least partly.
Since I presume you're working in VB.net, the basic structure of what you want performed is outlined in the short snippet above.
For example: The method Count (of the object String) exists in both C# and in VB.
Hope it helps a bit at least!