5 digit PIN into a 24 bit value - hex

I have a task where I need to convert a 5 digit PIN into a 24 bit value, split into three bytes which is then sent to a database as a string using a carriage return [0D]. The guide says that each byte is a hexadecimal value of the corresponding ASCII character.
I have written code that converts the 5 digit PIN into a hex number which is then split into three parts to form the three bytes. I have written a program to test the code and it works well until one of the bytes become 0D which also signifies a carriage return.
For example: PIN 67085 converts to 1060D in hex and is sent as bytes of [01][06][0D]. The 0D byte seems to be prematurely finalising the string and so returning an incorrect result from the database.
I a bit of a noob when it comes to decimal / hexidecimal / ASCII conversion... how do I convert the PIN into the required string without triggering a carriage return before the end of the string?

Related

Simple string encryptation - safety of higher ascii characters

I am trying to create a simple encryptation scheme for strings. Each character of the string is given another ascii value.
It entails writing ascii characters upto 246 to a simple file on disk.
I want to find out if it is safe to write these special characters to the disk or can it cause untoward results. Thanks for your help.
Edit: I am considering algorithm similar to following:
* Convert each character of string to its integer number (hence 110 for 'n' and 122 for 'z')
* Double that number (get 220 and 244)
* Convert this to character (will get extended ascii codes)
* Save these characters to file.
Is it safe to save these extended ascii characters to disk files using usual text file writing functions?
There is only a limited set of ASCII characters. There are 95 printable characters such as 'A' but also the space character. There are 33 printable characters such as Line Feed, Carriage Return, NUL but also DELETE. So you cannot use 246 characters of ASCII as there are only 128 total available. ASCII is strictly 7 bits giving you 2^7 = 128 possible values.
Even if you would use the ISO 8859 Latin character set or the Windows-1252 character set you would still have the unprintable control characters to deal with, leaving you with 256 - 33 - 5 characters or 218 characters. Windows-1252 still has 5 undefined characters.
What you can do is of course save your data as bytes. Each byte has 256 possible values (usually 0 to 255 or -128 to 127). As long as you open files as binary this pose no problem.
You can of course store as many characters in a file as you want, up to the file system or operating system limit. So I presume you didn't ask that.

How do I convert a signed 16-bit hexadecimal to decimal?

I have a very long sequence of data stored as unsigned 16-bit PCM (it's audio). Using Frhed, I can view the file as hex. I'd like to convert the hex into decimal. So far I've exported into a csv file and attempted to convert in R using as.integer(). However, this doesn't seem to take into account that the values are signed.
You can convert hex text strings to decimal digits using strtoi. You will need to specify that the base is 16.
HexData = c("A167", "AE8F", "6A99", "0966", "784D", "A637", "102D", "4521")
strtoi(HexData, base=16L)
[1] 41319 44687 27289 2406 30797 42551 4141 17697
This is assuming unsigned data. Your question mentions both signed and unsigned so I am not quite sure which you have.

What causes XOR encryption to return a "blank"?

What is the cause of certain characters to be blank when using XOR encryption? Furthermore, how can this be compensated for when decrypting?
For instance:
....
void basic_encrypt(char *to_encrypt) {
char c;
while (*to_encrypt) {
*to_encrypt = *to_encrypt ^ 20;
to_encrypt++;
}
}
will return "nothing" for the character k. Clearly, character decay is problematic for decryption.
I assume this is caused by the bit operator, but I am not very good with binary so I was wondering if anyone could explain.
Is it converting an element, k, in this case, to some spaceless ASCII character? Can this be compensated for by choosing some y < x < z operator where x is the operator?
Lastly, if it hasn't been compensated for, is there a realistic decryption strategy for filling in blanks besides guess and check?
'k' has the ASCII value 107 = 0x6B. 20 is 0x14, so
'k' ^ 20 == 0x7F == 127
if your character set is ASCII compatible. 127 is \DEL in ASCII, which is a non-printable character, so won't be displayed if you print it out.
You will have to know the difference between bytes and characters to understand which is happening. On the one hand you have the C char type, which is simply a presentation of a byte, not a character.
In the old days each character was mapped to one byte or octet value in a character encoding table, or code page. Nowadays we have encodings that take more bytes for certain characters, e.g. UTF-8, or even encodings that always take more than one byte such as UTF-16. The last two are unicode encodings, which means that each character has a certain number value and the encoding is used to encode this number into bytes.
Many computers will interpret bytes in ISO/IEC 8859-1 or Latin-1, sometimes extended by Windows-1252. These code pages have holes for control characters, or byte values that are simply not used. Now it depends on the runtime system how these values are handled. Java by default substitutes an ? character in place of the missing character. Other runtimes will simply drop the value or - of course - execute the control code. Some terminals may use the ESC control code to set the color or to switch to another code page (making a mess of the screen).
This is why ciphertext should be converted to another encoding, such as hexadecimals or Base64. These encodings should make sure that the result is readable text. This takes care of the cipher text. You will have to choose a character set for your plain text too, e.g. simply perform ASCII or UTF-8 encoding before encryption.
Getting a zero value from encryption does not matter because once you re-xor with the same xor key you get the original value.
value == value
value XOR value == 0 [encryption]
( value XOR value ) XOR value == value [decryption]
If you're using a zero-terminated string mechanism, then you have two main strategies for preventing 'character degradation'
store the length of the string before encryption and make sure to decrypt at least that number of characters on decryption
check for a zero character after decoding the character

ColdFusion: Integer "0" doesn't convert to ASCII character

I have a string (comprised of a userID and a date/time stamp), which I then encrypt using ColdFusion's Encrypt(inputString, myKey, "Blowfish/ECB/PKCS5Padding", "Hex").
In order to interface with a 3d party I have to then perform the following:
Convert each character pair within the resultant string into a HEX value.
HEX values are then represented as integers.
Resultant integers are then output as ASCII characters.
All the ASCII characters combine to form a Bytestring.
Bytestring is then converted to Base64.
Base64 is URL encoded and finally sent off (phew!)
It all works seamlessly, APART FROM when the original cfEncrypted string contains a "00".
The HEX value 00 translates as the integer (via function InputBaseN) 0 which then refuses to translate correctly into an ASCII character!
The resultant Bytestring (and therefore url string) is messed up and the 3d party is unable to decipher it.
It's worth mentioning that I do declare: <cfcontent type="text/html; charset=iso-8859-1"> at the top of the page.
Is there any way to correctly output 00 as ASCII? Could I avoid having "00" within the original encrypted string? Any help would be greatly appreciated :)
I'm pretty sure ColdFusion (and the Java underneath) use a null-terminated string type. This means that every string contains one and only one asc(0) char, which is the string terminator. If you try to insert an asc(0) into a string, CF is erroring because you are trying to create a malformed string element.
I'm not sure what the end solution is. I would play around with toBinary() and toString(), and talk to your 3rd party vendor about workarounds like sending the raw hex values or similar.
Actually there is a very easy solution. The credit card company who is processing your request needs you to convert it to lower case letters of hex. The only characters processed are :,-,0-9 do a if else and convert them manually into a string.

Printing out hex values of a char* array in C gives odd values for binary input

Here's an odd problem that's been stumping me for a bit.
The program is written in C89, and it reads a file into a char* array 16 bytes at a time (using fread and a size of sizeof(char)). The file is fopen'd with the "rb" flags. The array is then passed into a function that basically takes the 16 hex values and sticks it into a string, each value seperated by a space.
Here's where the weirdness comes in. The function produces a nice hex dump, 16 bytes at a time, for a text file input that I have. But it screws up if I try it on a small bitmap image -- I end up with output in the string like ffffff88 instead of just 88.
The hex values are placed into the output string using sprintf("%02x ", input[i]); in a loop.
Why would this work properly for some files but not others?
In C the char is treated as a signed value, unless you specify it as unsigned. It seems that when you pass parameters to a function, that when the parameter happens to be a char, it's 'padded out' to the size of a regular integer. If you don't clue the compiler in that this should be done in an unsigned way, 128 becomes 0xFFFFFF80, and so on.
So, the sign extension happens before the print formatter ever gets to look at the value. What this means is that
printf("%02X", (unsigned) input[i]);
won't solve your problem, as the value of input[i] will be sign extended, so all values from 128 to 255 are treated as -127 to -1 and become 0xFFFFFF80 to 0xFFFFFF, then cast, whereas
printf("%02X", ((unsigned char *) input)[i] );
will do the trick, but is kind of ungainly and hard to read. Best to make the type of input[] be unsigned char in the first place.
What you see is the result of sign extension from the char to int, using unsigned char * or casting to unsigned char before the cast to int is (implicitly?) performed should fix your problem.

Resources