Using strconv for negative hex values in Go - hex

I've been building an assembler for no good reason the past day or so using Go so I can get familiar with the language. It's my first real program using Go so I expected problems, but I have a consistent bug coming up time and time again. I just figured out other hacky ways to fix it in other cases, but this time I think I need an answer so I feel like I'm actually doing this right.
Basically, I have to parse tons of byte values. Some of these are signed bytes so -1 = 0xFF and so on. When calculating the address of a label I need to find the offset of it from the current address. The following code is a stripped down basic version of what I use to get the offset:
// lbladdr holds the target label address
// address holds current address in memory
// label[x] holds the offset
if address > lbladdr {
lbladdr -= address
}
label[x] = strconv.FormatInt(int64(lbladdr), 16)
This works for positive values, but when I get a negative address (address > lbladdr) then instead of getting a value like FE I get -2. I don't get why the standard library would append a negative sign to a hex number and I haven't been able to find anything in the documentation about it. I've looked a lot of other places but I can't seem to find anyone with the same problem either.
I hope it's just something on my end that is a simple fix.

It's perfectly reasonable to use a negative sign on hexadecimal numbers. I know that when working with assembly it's common to use the actual bitpattern for the register you are representing in hex to represent the signs. However Go doesn't know you are doing that. Neither is go's formatting function written to support hex values as they would be in a CPU register. Further the bitpatterns will differ depending on the register size (16 vs 32 vs 64 and big vs little endian). you would be storing them in. So the base isn't enough to print them the way you want. You will need to write your own formatting lib that supports formatting for the type of Register you want to represent.

It's by design: http://golang.org/src/pkg/strconv/itoa.go?s=628:668#L8
What you may want is to cast to uint64:
package main
import (
"fmt"
"strconv"
)
func main() {
i := -1
fmt.Printf("%x\n", uint64(i))
fmt.Println(strconv.FormatUint(uint64(i), 16))
}

Related

Wiegand card numbers are seen different on Hikvision and ZKteco

I have a problem with two access control panels, one is Hikvision and the other one is a ZKTeco CCA-400, those two panels see the Wiegand card in a different way, this is a big problem because I cannot import cards from ZKteco to Hikvision or the other way around.
Currently I have a card that is physically labeled with the following:
0002821060 043,03012
Hikvision panel sees the card as: 2821060
ZKTeco panel sees the card as: 04303012
My final goal is to understand why is this happening and build a custom Wiegand rule on the Hikvision in order to transform the card id's to be seen identical by both panels.
I searched and couldn't figure it out, so in my pursuit to debug this issue I connected a Wiegand reader to a Arduino UNO just to see that is coming on the wire from the reader, the results just made the problem even confusing:
I tried to Wiegand libraries:
https://github.com/paulo-raca/YetAnotherArduinoWiegandLibrary
and
https://github.com/monkeyboard/Wiegand-Protocol-Library-for-Arduino
Surprise!
The first library sees the card as:
Read 26 bits. 0001010110000101111000100100000000
FC = 43, CC = 3012
This is exactly what the ZKTeco panel sees.
The second library sees the card as:
Card readed: 24bits / 2B0BC4
That in decimal is 2821060, exactly what the Hikvision is seeing.
Can anyone explain to me why this is happening ? From reading the docs of the protocol is pretty straight forward and should not really have two independent ID's.
Hopefully I managed to explain the issue in a good way.
Thanks!
It sounds like the difference in what you are seeing is the two parity bits. Each half of the number encoded into the card has its own parity bit, with one half odd parity, and the other half even parity. In addition to detecting read errors, these two bits allow detection of use of a Wiegand card normally vs. upside-down.
You might check that by determining the reaction of the two devices to running the card through with the front side toward the back. My guess would be the one that only reports 24-bits may ignore reversed reads, but the other might report a different number (with bits reversed from the first one.)
I worked for Kastle Systems on what was probably the first commercial application of Wiegand cards for security almost 40 years ago. The parity scheme was similar to that used on UPC barcode readers. I see there are still documents out on the web describing the, Wiegand Kastle format 32-bit format, which looks like it may be helpful to you.
I managed to sort this out, it seems that ZKTeco and Hikvision handles the conversion from HEX to DEC in a different way, that's the reason there are two different numbers on the card.
So it goes like this, we have a card that has physically printed the following sequence of numbers: 0002821060 043,03012
We convert 2821060 to HEX = 2B0BC4 ( This is what ZKTeco sees )
For Hikvision:
We convert 2B to DEC = 43
We convert 0BC4 to DEC = 3012
The result decimal number is 43 3012, pretty close to what the access panel sees. Now, we have to pad it so it has 8 digits like this:
04303012
If the first bits are <100 in decimal we have to add a 0 in front.
We also need to pad the rest of the bits so the second part reaches a length of 5 digits.
Conclusion:
Hikvision correctly converts the card to Wiegand 26 format ( facility code + card id ), ZKTeco instead converts the entire card number to decimal directly without splitting the facility id / card id.
Hopefully this will be helpful to other people having to deal with this type of access control panels.
I wrote a fragment of messy code that will convert a ZK exported personel file to Hikvision card format.
import sys
def convert(dec):
h = hex(dec)
h = h[2:]
#print "HEX {}".format(h)
first = h[:2]
first = int(h[:2], 16)
if first < 100:
first = "0{}".format(first)
second = int(h[2:6],16)
first = str(first)
second = str(second)
if len(first)+len(second) == 8:
final = "{}{}".format(first,second)
else:
final = "{}0{}".format(first,second)
#print "HIK {}".format(final)
#print "ZK {}".format(int(h,16))
return str(final)
pid=1
with open("zk.csv") as f:
lis = [line.split(",") for line in f]
for i, x in enumerate(lis):
persid = pid
if x[1] == "":
name = "Fara nume"
else:
name = "{} {}".format(x[1], x[2])
cardid = convert(int(x[3]))
if cardid[:1] == "0":
cardid = "'{}".format(cardid)
print "{},NAN,{},1,,,,,{},,".format(pid, name, cardid)
pid+=1
This is the only post on internet I am finding on this topic. I report similar issue. Please do not delete as was done previously because this might help someone.
What I did is convert serialized RFID to site+cardID (hikvision way) with Excel:
M88 is DEC2HEX(L88) (M88 is the Hex of the serialized card number)
first 3 decimal digits
=IF(LEN(HEX2DEC(MID(M88;1;2)))=1;"00"&HEX2DEC(MID(M88;1;2));IF(LEN(HEX2DEC(MID(M88;1;2)))=2;"0"&HEX2DEC(MID(M88;1;2));HEX2DEC(MID(M88;1;2))))
last 5 decimal digits
=IF(LEN(HEX2DEC(MID(M88;3;4)))<5;"0"&HEX2DEC(MID(M88;3;4));HEX2DEC(MID(M88;3;4)))
This is a good calculator I've found but not suitable for hundreds of lines of RFIDs
https://btrockford.com/security/card-access-control/proximity-card-calculator/
Probably there is an option to use custom Wiegand rules to modify the hikvision default behavior (I didn't have success with that till now).

Finding similar hashes

I'm trying to find 2 different plain text words that create very similar hashes.
I'm using the hashing method 'whirlpool', but I don't really need my question to be answered in the case or whirlpool, if you can using md5 or something easier that's ok.
The similarities i'm looking for is that they contain the same number of letters (doesnt matter how much they're jangled up)
i.e
plaintext 'test'
hash 1: abbb5 has 1 a , 3 b's , one 5
plaintext 'blahblah'
hash 2: b5bab must have the same, but doesnt matter what order.
I'm sure I can read up on how they're created and break it down and reverse it, but I am just wondering if what I'm talking about occurs.
I'm wondering because I haven't found a match of what I'm explaining (I created a PoC to run threw random words / letters till it recreated a similar match), but then again It would take forever doing it the way i was dong it. and was wondering if anyone with real knowledge of hashes / encryption would help me out.
So you can do it like this:
create an empty sorted map \
create a 64 bit counter (you don't need more than 2^63 inputs, in all probability, since you would be dead before they would be calculated - unless quantum crypto really takes off)
use the counter as input, probably easiest to encode it in 8 bytes;
use this as input for your hash function;
encode output of hash in hex (use ASCII bytes, for speed);
sort hex on number / alphabetically (same thing really)
check if sorted hex result is a key in the map
if it is, show hex result, the old counter from the map & the current counter (and stop)
if it isn't, put the sorted hex result in the map, with the counter as value
increase counter, goto 3
That's all folks. Results for SHA-1:
011122344667788899999aaaabbbcccddeeeefff for both 320324 and 429678
I don't know why you want to do this for hex, the hashes will be so large that they won't look too much alike. If your alphabet is smaller, your code will run (even) quicker. If you use whole output bytes (i.e. 00 to FF instead of 0 to F) instead of hex, it will take much more time - a quick (non-optimized) test on my machine shows it doesn't finish in minutes and then runs out of memory.

Driving Dual 7 Segment Display Using Arduino

Okay, so I am trying to drive a 7 segment based display in order to display temperature in degrees celcius. So, I have two displays, plus one extra LED to indicate positive and negative numbers.
My problem lies in the software. I have to find some way of driving these displays, which means converting a given integer into the relevant voltages on the pins, which means that for each of the two displays I need to know the number of tens and number of 1s in the integer.
So far, what I have come up with will not be very nice for an arduino as it relies on division.
tens = numberToDisplay / 10;
ones = numberToDisplay % 10;
I have admittedly not tested this yet, but I think I can assume that for a microcontroller with limited division capabilities this is not an optimal solution.
I have wracked my brain and looked around for a solution using addition/subtraction/bitwise but I cannot think of one at all. This division is the only one I can see.
For this application it's fine. You don't need to get bothered with performance in a simple thermometer.
If however you do need something quicker than division and modulo, then bitwise operations come to help. Basically you would use bitwise & operator, to compare your value to display with patterns describing digits to be displayed on the display.
See the project here for example: http://fritzing.org/projects/2-digit-7-segment-0-99-counting-with-arduino/
You might also try using a 7-seg display driver chip to simplify your output and save pins. The MC14511BCP (a "4511") is a good one. It'll translate binary coded decimal (BCD) to the appropriate 7-seg configuration. Spec sheets are available here and they can be commonly found at electronics parts stores online.

ExtendScript's UnitValue

So I can't find, for the life of me, a clear breakdown of the components of ExtendScript's UnitValue object. Every source I found had something to do with Adobe, and didn't explain it. I'd really like to have a full reference on it, but if no one can find one, I need at least a few questions answered concerning it.
First, what are its constructors? I've seen UnitValue(10,'px') which makes sense, but I've also seen UnitValue(20,20)
Second, how can you convert from one unit to another?
Third, how can you find its value and its unit?
I think I've seen uv.value but nothing getting the unitsLastly, as my tags indicate, this is for Adobe, of course, since I've never seen or heard of any other program that uses ExtendScript.
UnitValue is documented in the Adobe JavaScript Tools Guide.
In particular, you create an object with v = new UnitValue(number, unit), where unit is a string value like in (inch), mm (millimeter), pt (point), px (pixel), etc.
To convert a UnitValue to an actual number, use the as method, e.g. v.as("cm") to convert v into centimeters.
Well, no one else seemed to know, and I finally figured some of it out, so I guess I'll answer it myself:
<This site> was a little helpful as a documentation, but I think Adobe functions slightly different from it.
UnitValue's main constructor is:
UnitValue(numericalvalue,unit)
I've also seen an alternative that accepts one string:
UnitValue("42 in")
For conversion, UnitValue comes with a handy as method which accepts the unit to convert to (as a string), and then returns its measurement in that unit, i.e.:
UnitValue(5,'ft').as('in') === 60
(Note, according to the reference I found, I believe the as method should return the UnitValue instance after being converted to the unit indicated; Adobe's implementation, however, seems to instead merely return the value - therefore I'm use the type-equality operator above to show Adobe's method)
For getting the numerical value and measurement unit, the following two properties exist:
UnitValue.value // number: the numerical value
UnitValue.type // string: the unit of measurement
This is all I could find by my research. If someone has a better answer, post it, and I may accept it.
What's really interesting to me is the baseValue property which allows us to change the frame of reference for the conversion. For instance:
var startUnit = UnitValue(500, "px");
startUnit.baseValue = UnitValue(1 / 72, "in"); // from what I can tell this is the default baseUnit value
$.writeln(v.as("in")); // returns 6.94444444444444 which is what 500px # 72 dpi is as expressed in inches
startUnit.baseValue = UnitValue(1 / 300, "in"); // set to 300dpi
$.writeln(v.as("in")); // returns 1.66666666666667 which is what 500px # 300 dpi is as expressed in inches
I think the default baseValue is always UnitValue(1/72, "in") even if the app.preferences.rulerUnits is set to any other type of measurement but I haven't really looked into it much

Program to mimic scanf() using system calls

As the Title says, i am trying out this last year's problem that wants me to write a program that works the same as scanf().
Ubuntu:
Here is my code:
#include<unistd.h>
#include<stdio.h>
int main()
{
int fd=0;
char buf[20];
read(0,buf,20);
printf("%s",buf);
}
Now my program does not work exactly the same.
How do i do that both the integer and character values can be stored since my given code just takes the character strings.
Also how do i make my input to take in any number of data, (only 20 characters in this case).
Doing this job thoroughly is a non-trivial exercise.
What you show does not emulate sscanf("%s", buffer); very well. There are at least two problems:
You limit the input to 20 characters.
You do not stop reading at the first white space character, leaving it and other characters behind to be read next time.
Note that the system calls cannot provide an 'unget' functionality; that has to be provided by the FILE * type. With file streams, you are guaranteed one character of pushback. I recently did some empirical research on the limits, finding values that the number of pushed back characters ranged from 1 (AIX, HP-UX) to 4 (Solaris) to 'big', meaning up to 4 KiB, possibly more, on Linux and MacOS X (BSD). Fortunately, scanf() only requires one character of pushback. (Well, that's the usual claim; I'm not sure whether that's feasible when distinguishing between "1.23e+f" and "1.23e+1"; the first needs three characters of lookahead, it seems to me, before it can tell that the e+f is not part of the number.)
If you are writing a plug-in replacement for scanf(), you are going to need to use the <stdarg.h> mechanism. Fortunately, all the arguments to scanf() after the format string are data pointers, and all data pointers are the same size. This simplifies some aspects of the code. However, you will be parsing the scan format string (a non-trivial exercise in its own right; see the recent discussion of print format string parsing) and then arranging to make the appropriate conversions and assignments.
Unless you have unusually stringent conditions imposed upon you, assume that you will use the character-level Standard I/O library functions such as getchar(), getc() and ungetc(). If you can't even use them, then write your own variants of them. Be aware that full integration with the rest of the I/O functions is tricky - things like fseek() complicate matters, and ensuring that pushed-back characters are properly consumed is also not entirely trivial.

Resources