is there a way to convert an integer to be always a 4 digit hex number using Lua - lua

I'm creating a Lua script which will calculate a temperature value then format this value as a 4 digit hex number which must always be 4 digits. Having the answer as a string is fine.
Previously in C I have been able to use
data_hex=string.format('%h04x', -21)
which would return ffeb
however the 'h' string formatter is not available to me in Lua
dropping the 'h' doesn't cater for negative answers i.e
data_hex=string.format('%04x', -21)
print(data_hex)
which returns ffffffeb
data_hex=string.format('%04x', 21)
print(data_hex)
which returns 0015
Is there a convenient and portable equivalent to the 'h' string formatter?

I suggest you try using a bitwise AND to truncate any leading hex digits for the value being printed.
If you have a variable temp that you are going to print then you would use something like data_hex=string.format("%04x",temp & 0xffff) which would remove the leading hex digits leaving only the least significant 4 hex digits.
I like this approach as there is less string manipulation and it is congruent with the actual data type of a signed 16 bit number. Whether reducing string manipulation is a concern would depend on the rate at which the temperature is polled.
For further information on the format function see The String Library article.

Related

How to test if a string character is a digit?

How can I test if a certain character of a string variable is a digit in SPSS (and then apply some operations, depending on the result)?
So let's for example say, I have a variable that reflects the street number. Some street numbers have additional character at the end e.g. "12b". Now let's further assume that I extracted the last character (that could be a digit, or the additional letter) into a string variable. After that I'd like to check if this character is a digit or a letter. How can this be done?
I managed to do this with the MAX function, where "mychar" is the character variable to be checked:
COMPUTE digitcheck = (MAX(mychar,"9")="9").
If the content of "mychar" is a digit [0-9] the result of the MAX function will be "9" otherwise the MAX function will return the letter and the equality test fails.
In this way you can also check if a whole string variable contains a letter or not. It looks pretty ugly though, because you have to compare every single character of your string variable.
compute justdigits = (MAX((CHAR.SUBSTR(mystr,1,1), CHAR.SUBSTR(mystr,2,1), CHAR.SUBSTR(mystr,3,1), ..., CHAR.SUBSTR(mystr,n,1),"9")="9").
If you try to turn a letter into a number then it becomes a missing value. Therefore, to test whether a character is a digit, you can do this:
if not missing(number(YourCharacter,f1)) .....
The same test can determine whether a string has only a number in it or not:
compute OnlyNumber=(not missing(number(YourString,f10))).
Note: using the number command on strings will produce warning messages which you can of course ignore.

Delphi base convert Binary to Decimal

Im converting binary to decimal and Im converting Decimal to binary. My problem is Length of the binary integer. For example:
Convertx("001110",2,10) = 14
Convertx("14",10,2) = 1110
But length of the binary is NOT constant, So How can I get exact original binary with zeros front of it? How can I get "001110" instead of "1110" ?
I m using this function in Delphi 7. -> How can I convert base of decimal string to another base?
The function you are using returns a string that is the shortest length required to express the value you have converted.
Any zeroes in front of that string are simply padding - they do not alter the binary value represented. If you need a string of a minimum length then you need to add this "padding" yourself. e.g. if you want a binary representation of a "byte" (i.e. 8 binary digits) then the minimum length you would need is 8:
binStr := Convertx("14",10,2);
while Length(binStr) < 8 do
binStr := '0' + binStr;
If you need the exact number of zeroes that were included in the "padding" of some original binary value when converting from binary to decimal and then back to "original" binary again, then this is impossible unless you separately record how many padding zeroes there were or the length of the original string, including those zeroes.
i.e. in your example, the ConvertX function has no idea (and now way to figure out) that the number "14" it is asked to convert to binary was originally converted from a 6 digit binary string with 2 leading zeroes, rather than an 8 digit binary with 4 leading zeroes (or a 16 digit binary with 12 leading zeroes, etc etc).
What you are hoping for is impossible. Consider
Convertx('001110', 2, 10)
and
Convertx('1110', 2, 10)
These both return the same output, 14. At that point there is no way to recover the length of the original input.
The way forward is therefore clear. You must remember the length of the original binary, as well as the equivalent decimal. However, once you have reached that conclusion then you might wonder whether there is an even simpler approach. Just remember the original binary value and save yourself having to convert back from decimal.

what is the difference between binary and binary coded decimal?

I'm studying encoders, which convert decimal to a code such as binary or binary coded decimal. What is binary coded decimal? Is it different from binary?
It's very late but I saw this so I thought I might answer. So binary coded decimal is a way to denote larger binary numbers in decimal form, except each digit is represented in binary for example.
1111(binary) = 15(decimal)
1111(binary) = 0001 0101(BCD)
so the bcd form of 1111 is two 4 bits numbers where the first 4 bit number in decimal is 1 and the second in decimal is 5, thus giving us 15. The way to calculate this is through an algorithm called double dabble.
(B)inary (C)oded (D)ecimal data usage is found mostly in Assembler programs. On mainframes, it was mostly used to save half a byte, typically to allow an 8-digit date to be stored in a (four-byte) fullword as YYYYMMDD, avoiding a full binary conversion while also keeping the date more "eye friendly" format (i.e. easier to see in a file dump).
IBM Mainframe Assembler provides a special instruction - MVO: (M)o(V)e with (O)ffset - enabling very easy conversion from Packed Decimal (i.e. COMP-3 in COBOL) to BCD format (and vice-versa) without using an algorithm.
Example: Assume a date of 31-DEC-2017 in YYYYMMDD (8-byte) format is to be converted to a 8-digit BCD format field (4-bytes).
(1) Use the PACK instruction to convert the 8-char DATE into 5-bytes PACKED
(2) Use the MVO instruction to move the 8 significant binary decimal digits to the BCD field
[Note length override "...BCD(5)...": so sign X'F' from PACKED is shifted into byte after the BCD field]
BCD now contains X'20171231'
SAMPLE CSECT
[...]
(1) PACK PACKED,DATE C'20171231' BECOMES X'020171231F' IN PACKED
(2) MVO BCD(5),PACKED X'020171231F' BECOMES X'20171231' IN BCD
[...]
BCD DS XL4
PACKED DS PL5
DATE DC CL8'21071231'
Likewise, to convert an 8-digit BCD date to an 8-char DATE is a simple sequence of 3 instructions:
(1) Insert sign into rightmost byte of a 5-byte packed decimal field
[think of this as restoring the sign shifted out in step 2 "MVO BCD(5),PACKED" in the first example, above]
(2) Use the MVO instruction to extract the 8 binary decimal digits into the 5-byte packed decimal field
(3) Use UNPK to convert the 5-byte packed decimal field to an 8-char date
DATE now contains C'20171231'
SAMPLE CSECT
[...]
(1) MVI PACKED+(L'PACKED-1),X'0F' INSERT SIGN (PACKED BECOMES X'........0F'
(2) MVO PACKED,BCD X'20171231' BECOMES X'020171231F' IN PACKED
(3) UNPK DATE,PACKED X'020171231F' BECOMES C'20171231' IN DATE
[...]
BCD DC XL4'20171231'
PACKED DS PL5
DATE DS CL8

Converting HEX to ASCII in Lua Dissector

I'm trying to take HEX bytes and display them as their ASCII values. If someone could point me reasonably firmly in the right direction I'd be obliged. Tried any number of uint-type commands, and working with buffer(x, 2) as an argument.
I'm not sure what you mean by hex bytes, but the relevant functions are:
string.byte, which converts chars to numerical codes
string.char, which converts numerical codes to chars
For a single character in hexadecimal, you can use string.byte as mentioned by lhf. For longer sequences, you can create a loop in Lua, but that is not very efficient since it involves a lot of copying.
Since Wireshark 1.11.3 there is a Struct.fromhex function that converts a string of hexadecimal characters to the binary equivalent.
Example:
-- From hex to bytes (with no separators)
assert(Struct.fromhex("5753") == "WS")
-- From hex to bytes (using a single space as separator)
assert(Struct.fromhex("57 53", " ") == "WS")
Similarly, there is a Struct.tohex function that converts from bytes to hex.

What is an Illegal octal digit?

I'm trying to make an array of zip codes.
array = [07001, 07920]
This returns :
array = [07001, 07920]
^
from (irb):12
from :0
Never seen this before. Any workarounds?
Ruby is interpreting numbers that have a leading 0 as being in octal (base 8). Thus the digits 8 and 9 are not valid.
It probably makes more sense to store ZIP codes as strings, instead of as numbers (to avoid having to pad with zeroes whenever you display it), as such: array = ["07001", "07920"]
Numbers that start with 0 are assumed to be in octal format, just like numbers that start with 0x are assumed to be in hexadecimal format. Octal digits only go from 0 to 7, so 9 is simply not legal in an octal number.
The easiest workaround would be to simply write the numbers in decimal format: 07001 in octal is the same as 3585 in decimal (I think). Or did you mean to write the numbers in decimal? Then, the easiest workaround is to leave off the leading zeroes: 07001 is the same as 7001 anyway.
However, you mention that you want an array of ZIP codes. In that case, the correct solution would be to use, well, an array of ZIP codes instead of an array of integers, since ZIP codes aren't integers, they are ZIP codes.
Your array is of numbers, so the leading zero causes it to be interpreted as octal (valid digits 0-7). If these are zip codes, and the leading zero is significant, they should probably be strings.

Resources