How to convert a group of Hexadecimal to Decimal (Visual Studio ) - hex

I want to retrieve like in Pic2, the values in Decimal. ( hardcoded for visual understanding)
This is the codes to convert Hex to Dec for 16 bit:
string H;
int D;
H = txtHex.Text;
D = Convert.ToInt16(H, 16);
txtDec.Text = Convert.ToString(D);
however it doesn't work for a whole group

So the hex you are looking at does not refer to a decimal number. If it did refer to a single number that number would be far too large to store in any integral type. It might actually be too large to store in floating point types.
That hex you are looking at represents the binary data of a file. Each set of two characters represents one byte (because 16^2 = 2^8).
Take each pair of hex characters and convert it to a value between 0 and 255. You can accomplish this easily by converting each character to its numerical value. In case you don't have a complete understanding of what hex is, here's a map.
'0' = 0
'1' = 1
'2' = 2
'3' = 3
'4' = 4
'5' = 5
'6' = 6
'7' = 7
'8' = 8
'9' = 9
'A' = 10
'B' = 11
'C' = 12
'D' = 13
'E' = 14
'F' = 15
If the character on the left evaluates to n and the character on the right evaluates to m then the decimal value of the hex pair is (n x 16) + m.
You can use this method to get your values between 0 and 255. You then need to store each value in an unsigned char (this is a C/C++/ObjC term - I have no idea what the C# or VBA equivalent is, sorry). You then concatenate these unsigned char's to create the binary of the file. It is very important that you use an 8 bit type to store these values. You should not store these values in 16 bit integers, as you do above, or you will get corrupted data.
I don't know what you're meant to output in your program but this is how you get the data. If you provide a little more information I can probably help you use this binary.

You will need to split the contents into separate hex-number pairs ("B9", "D1" and so on). Then you can convert each into their "byte" value and add it to a result list.
Something like this, although you may need to adjust the "Split" (now it uses single spaces, returns, newlines and tabs as separator):
var byteList = new List<byte>();
foreach(var bytestring in txtHex.Text.Split(new[] {' ', '\r', '\n', '\t'},
StringSplitOptions.RemoveEmptyEntries))
{
byteList.Add(Convert.ToByte(bytestring, 16));
}
byte[] bytes = byteList.ToArray(); // further processing usually needs a byte-array instead of a List<byte>
What you then do with those "bytes" is up to you.

Related

Usage of the pipe " | " in a less calculation [duplicate]

we can do the following to convert:
var a = "129.13"|0, // becomes 129
var b = 11.12|0; // becomes 11
var c = "112"|0; // becomes 112
This seem to work but not sure if this is a standard JS feature. Does any one have any idea if this is safe to use for converting strings and decimals to integers ?
Yes, it is standard behavior. Bitwise operators only operate on integers, so they convert whatever number they're give to signed 32 bit integer.
This means that the max range is that of signed 32 bit integer minus 1, which is 2147483647.
(Math.pow(2, 32) / 2 - 1)|0; // 2147483647
(Math.pow(2, 32) / 2)|0; // -2147483648 (wrong result)

How to parse two characters at a time for one Iteration?

I have a written query for matching 2 characters and parse the data but I feel that the way i did is wrong. Let me share my logic with you
DEFINE VARIABLE I AS INTEGER NO-UNDO.
DEFINE VARIABLE cData AS CHARACTER NO-UNDO.
DEFINE VARIABLE cParsData AS CHARACTER NO-UNDO.
ASSIGN
cData = 'PRRSCLPP0123456789'.
DO I = 1 TO LENGTH(cData):
cParsData = SUBSTRING(cData,I).
IF cParsData MATCHES 'PP*' THEN MESSAGE SUBSTRING(cParsData,4,9).
END.
As you see the way i did is wrong and its parsing each character per iteration i think but what i need is it should parse two characters per iteration so that we can matches "PP". You can share or change the logic for different ways to get the same output
It is hard to imagine a reason for iterating through the string one character at a time looking for "PP" and then spitting out characters 4 through 13. It would be much simpler to do this:
define variable myData as character no-undo.
define variable foundIt as integer no-undo.
myData = "PRRSCLPP0123456789".
foundIt = index( myData, "PP" ).
if foundIt > 0 then
message substring( myData, 4, 9 ).
If there is a reason to go through that string one character at a time I think it must not be contained in your code sample or question.
On a side note: MATCHES "PP*" is equivalent to BEGINS "PP". It doesn't matter much in this case but it is a bad habit to needlessly throw MATCHES at string comparisons. Especially if that habit ends up in a WHERE clause. Using MATCHES in WHERE clauses will cause a table scan. Which is almost always a bad idea.
If you are trying to output N characters after the position that "PP" was found (rather than the hard-coded 4 through 13) you would do it like so (assuming that n = 9):
define variable myData as character no-undo.
define variable foundIt as integer no-undo.
myData = "PRRSCLPP0123456789".
foundIt = index( myData, "PP" ).
if foundIt > 0 then
message substring( myData, foundIt + 1, 9 ).
I dont quite understand what you want to do. Do you want to search the string and see if there's "PP" in it? Then you don't need to do it in an iteration. Simply
cData MATCHES "*PP*" will tell you that.
If "PP" is some kind of delimiter and you want to do something with the data before and after you can do:
DEFINE VARIABLE I AS INTEGER NO-UNDO.
DEFINE VARIABLE cData AS CHARACTER NO-UNDO .
DEFINE VARIABLE cParsData AS CHARACTER NO-UNDO.
ASSIGN
cData = 'PRRSCLPP0123456789'.
DO I = 1 TO LENGTH(cData):
cParsData = SUBSTRING(cData,I, 2).
IF cParsData = 'PP' THEN DO:
DISPLAY
SUBSTRING(cData, i + 2) FORMAT "x(20)" LABEL "After PP"
SUBSTRING(cData, 1, i - 1) FORMAT "x(20)" LABEL "Before PP".
END.
END.
This only works for one occurance of "PP" in the string though. You should try to explain better exactly what you are after.
You left a lot more information in a comment on another answer:
If PP really always is position 10 (and 11) or 20 (and 21) and you only want the follwing 10 chars then you can do:
DEFINE VARIABLE cData1 AS CHARACTER NO-UNDO.
DEFINE VARIABLE cData2 AS CHARACTER NO-UNDO.
/* Position 10 and 11 */
cData1 = 'PRRSCLAAAPP0123456789'.
/* Position 20 and 21 */
cData2 = 'PRRSCLAAAPRRSCLAAAPP9876543210AA'.
FUNCTION parse RETURNS CHARACTER
(INPUT cString AS CHARACTER ):
IF INDEX(cString, "PP") > 0 THEN
RETURN SUBSTRING(cString, INDEX(cString, "PP") + 2, 10 ).
ELSE
RETURN "".
END.
MESSAGE cData1 " ->" parse(cData1) SKIP
cData2 " ->" parse(cData2) VIEW-AS ALERT-BOX.

Need help understanding how gsub and tonumber are used to encode lua source code?

I'm new to LUA but figured out that gsub is a global substitution function and tonumber is a converter function. What I don't understand is how the two functions are used together to produce an encoded string.
I've already tried reading parts of PIL (Programming in Lua) and the reference manual but still, am a bit confused.
local L0_0, L1_1
function L0_0(A0_2)
return (A0_2:gsub("..", function(A0_3)
return string.char((tonumber(A0_3, 16) + 256 - 13 + 255999744) % 256)
end))
end
encodes = L0_0
L0_0 = gg
L0_0 = L0_0.toast
L1_1 = "__loading__\226\128\166"
L0_0(L1_1)
L0_0 = encodes
L1_1 = --"The Encoded String"
L0_0 = L0_0(L1_1)
L1_1 = load
L1_1 = L1_1(L0_0)
pcall(L1_1)
I removed the encoded string where I put the comment because of how long it was. If needed I can upload the encoded string as well.
gsub is being used to get 2 digit sections of A0_2. This means the string A0_3 is a 2 digit hexadecimal number but it is not in a number format so we cannot preform math on the value. A0_3 being a hex number can be inferred based on how tonubmer is used.
tonumber from Lua 5.1 Reference Manual:
Tries to convert its argument to a number. If the argument is already a number or a string convertible to a number, then tonumber returns this number; otherwise, it returns nil.
An optional argument specifies the base to interpret the numeral. The base may be any integer between 2 and 36, inclusive. In bases above 10, the letter 'A' (in either upper or lower case) represents 10, 'B' represents 11, and so forth, with 'Z' representing 35. In base 10 (the default), the number can have a decimal part, as well as an optional exponent part (see ยง2.1). In other bases, only unsigned integers are accepted.
So tonumber(A0_3, 16) means we are expecting for A0_3 to be a base 16 number (hexadecimal).
Once we have the number value of A0_3 we do some math and finally convert it to a character.
function L0_0(A0_2)
return (A0_2:gsub("..", function(A0_3)
return string.char((tonumber(A0_3, 16) + 256 - 13 + 255999744) % 256)
end))
end
This block of code takes a string of hex digits and converts them into chars. tonumber is being used to allow for the manipulation of the values.
Here is an example of how this works with Hello World:
local str = "Hello World"
local hex_str = ''
for i = 1, #str do
hex_string = hex_string .. string.format("%x", str:byte(i,i))
end
function L0_0(A0_2)
return (A0_2:gsub("..", function(A0_3)
return string.char((tonumber(A0_3, 16) + 256 - 13 + 255999744) % 256)
end))
end
local encoded = L0_0(hex_str)
print(encoded)
Output
;X__bJbe_W
And taking it back to the orginal string:
function decode(A0_2)
return (A0_2:gsub("..", function(A0_3)
return string.char((tonumber(A0_3, 16) + 13) % 256)
end))
end
hex_string = ''
for i = 1, #encoded do
hex_string = hex_string .. string.format("%x", encoded:byte(i,i))
end
print(decode(hex_string))

Maximum input number to URL shortener

Given the following code which encodes a number - how can I calculate the maximum number if I want to limit the length of my generated keys. e.g. setting the max length of the result of encode(num) to some fixed value say 10
var alphabet = <SOME SET OF KEYS>,
base = alphabet.length;
this.encode = function(num) {
var str = '';
while (num > 0) {
str = _alphabet.charAt(num % base) + str;
num = Math.floor(num / base);
}
return str;
};
You are constructing num's representation in base base, with some arbitrary set of characters as numerals (alphabet).
For n characters we can represent numbers 0 through base^n - 1, so the answer to your question is base^10 - 1. For example, using the decimal system, with 5 digits we can represent numbers from 0 to 99999 (10^5 - 1).
It's worth noting that you will not ever use some sub-n length strings such as '001' or '0405' (using the decimal system numerals) - so any string starting with the equivalent of 0 except '0' itself.
I imagine that, for the purpose of a URL shortener that is allowed variable length, this might be considered a waste. By using all combinations you could represent numbers 0 through base^(n+1) - 2, but it wouldn't be as straightforward as your scheme.

How to store the ASCII value in a character (Ada 83 Only)

How do I store the ascii value of an integer (say 33) in a character. I want something like this in Ada83, not 95
C: Code
char c = 10;
char *k = &c;
strncat (des, k, 1);
printf("%s",des);
Thank you!!
C : Character := Character'Val(10);
or
C : Character := ASCII.LF;
The first works in all versions of Ada. The second one was the standard way in Ada 83; it is now obsolescent. The newer way is
C : Character := Ada.Characters.Latin_1.LF;
More information: In Ada, Character is an enumeration type, not an integer type. Therefore, you can't assign an integer to it directly. The 'Val attribute is the Ada way to convert an integer to an enumeration; Enum_Type'Val(N) means "the Nth enumeration literal defined for the enumeration type, 0-relative". To go the other way, Enum_Type'Pos(E) returns the integer corresponding to the position of E in the enumeration list.

Resources