Inserting hex value in MySQL - mysql

I have created an SQL database using Java. I have a table created which has two columns, the first being a big integer which increments, the second I have tried defining it as a char, varchar and binary.
But I'm still not getting the desired functionality. Say I try and store a hex number 0a into the char column and I get an error. I appended 0x to the beginning and it seems to store, but when I print out the contents it is blank. Or in some cases I get characters such as '/' or '?'. I also tried using SQL explorer and it gives me the same result viewing the table,
My problem is I need to store an eight character hex string such as eb8d4ee6.
Could someone please advise me of how this can be done?

See http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html
MySQL supports hexadecimal values,
written using X'val', x'val', or 0xval
format, where val contains hexadecimal
digits (0..9, A..F). Lettercase of the
digits does not matter. For values
written using X'val' or x'val' format,
val must contain an even number of
digits. For values written using 0xval
syntax, values that contain an odd
number of digits are treated as having
an extra leading 0. For example, 0x0a
and 0xaaa are interpreted as 0x0a and
0x0aaa.
In numeric contexts, hexadecimal
values act like integers (64-bit
precision). In string contexts, they
act like binary strings, where each
pair of hex digits is converted to a
character:
You probably should store the Hex number in an integer column. You can then convert back to hex when selecting using the HEX() function.
E.g.,
INSERT INTO MyTable (`MyIntegerColumn`) VALUES (0xeb8d4ee6);

You can use a Json column:
And use JSON.stringify(hex) to insert and you can always get the result via select and compare too

Related

Filter only alphabetic values in tableau

I have column in tableau with following values:
1234
3456
6789
camp-1
camp-2
camp-3
I only want to show filter with values
camp-1
camp-2
camp-3
How can I only select the alphabetic values in filter in tableau?
Your example is not clear about what you want to include and what you want to exclude. To explain better, I took an elaborated example
Case-1 If you want to search/filter for digits at start, use this calculated field
REGEXP_MATCH([Field1], '^[0-9]')
Case-2 If you want to search for numbers anywhere, use this
REGEXP_MATCH([Field1], '(.*)[0-9]')
Case-3 If digits only are required
REGEXP_MATCH([Field1], '^[0-9]+$')
case-4 for alphabet at start use this
REGEXP_MATCH([Field1], '^[:alpha:]')
Results of all matches are shown below
Note Combining numbers anywhere AND alphabet at start you can filter out case1, case2 and case3 only.
Good Luck
If the Tableau column contains a mixture of numbers and text, the column will be a text column and all content will be considered as text. This reduces the problem to that of identifying specific rows that contain non-numeric values.
This requires some string manipulation and comparison. If you know that the structure of the content in those rows is predictable (eg the first character is always a letter when there are non numeric characters in the row) then a simple equation will filter on those rows:
if ascii(left([Text And Numbers],1) )>57 then 'text' else 'number' END
This exploits the observation that the ASCII decimal code for the digit 9 is 57 and most of the ASCII characters with higher codes are letters or punctuation (which is a fair assumption if nothing other than numbers, letters or punctuation are present in your data).
Obviously, if letters and numbers could appear anywhere in the string you need a more complex function but Tableau provides the option to use regular expressions which can code much more complex text analysis like is any alphabetic character present in a string (see this for some ideas of the appropriate regex expressions).

MySQL hex strings low bytes first

If I insert 0xFF into a binary column, MySql (5.7) assumes these are the high bytes.
e.g. if the column is BINARY(2):
+--------------------+
| HEX(binary_column) |
+--------------------+
| FF00 |
+--------------------+
Just for convenience, how would you get MySql to interpret a hex string normally?
P.S. Also tried UNHEX()
binary is not really a numerical datatype. It is a special type of string used to store binary data like files. In contrast to e.g. char, binary does not have a character map and comparisons are done with the numerical code.
That behaviour is similar as to how other programming languages treat strings and byte arrays, and is expected in mysql too, see The BINARY and VARBINARY Type:
When BINARY values are stored, they are right-padded with the pad value to the specified length. The pad value is 0x00 (the zero byte). Values are right-padded with 0x00 on insert, and no trailing bytes are removed on select. All bytes are significant in comparisons, including ORDER BY and DISTINCT operations. 0x00 bytes and spaces are different in comparisons, with 0x00 < space.
You seem to look for binary numbers, so you may want to use a numeric type. You can use e.g. int (or bit(16)) and still insert values like 0xFF (just not as '0xFF' without further casting), and you still can display them with e.g. hex(0xFF) in the way you want.
If you want to use binary values (or need large values > 8 byte), you can use lpad to fill them with leading zeros, e.g.
select hex(lpad(0xFF,2,0x0))
You have to know (or query) the size of your column, and you will probably run into a lot of issues with this, starting with the simple task of adding two binary values. So to keep it simple, use a numeric type.

Mysql: xor a string with a key

I want to Bitwise-XOR a string (actually its binary representation) with a KEY.
The result of the operation should be represented as HEX.
What I have:
'a' - the UTF-8 String to be changed.
'ACF123456' - the key in HEX.
Result seen as BIGINT:
select CONV(HEX('a'), 16, 10) ^ CONV('ACF123456', 16, 10);
Result seen as HEX:
select CONV( CONV(HEX('a'), 16, 10) ^ CONV('ACF123456', 16, 10), 10, 16);
Questions:
Is the conversion above done correctly?
What happens if the string is too long (i.e instead of 'a' we have 'a veeeeeery long string')? It seems that the conv() function has a limitation (is it the 64-bit precision from the documentation)? And besides the XOR operator ^ has also a limitation, related to the nr. of bits of the returned result. Any solutions that work for any string (a stored procedure is allowed)?
Thanks.
Your conversions look fine to me.
And as you point out, both CONV() and ^ have indeed a 64-bits precision.
2^64 = 16^16, therefore strings of more than 16 hexadecimal digits should convert to integers larger than 2^64. However, such strings will be brutally (silently) truncated from the left when attempting to convert them to integers.
The point of my solution here is to slice such strings. Obviously, the result may not be displayed as an integer, but only as a string representation.
Let #input be your "string to be changed" and #key, your "key".
Assign HEX(#input) to #hex_input. No problem here since HEX() works with strings.
Slice #hex_input into 16 hexadecimal digit long strings, starting from the right
Likewise, slice #key into 16 digit long strings.
Compute the X-OR of each 64-bit slice of #hex_input with each 64-bit slice of #key, starting from the right. Use CONV(#slice, 16, 10). If either #hex_input or #key has less slices than the other string, then X-OR the remaining slices of the other string with 0.
Convert each 64-bit number resulting from the X-OR in point 4. back into an hexadecimal string with UNHEX().
Reassemble the resulting slices. This is your result.
A three-columns TEMPORARY table could be used as an array to store slices of #hex_input, #mask and the resulting slices.
Put this all together into a stored procedure, and voilà!
You sound like you have some skills in MySQL, you should be able to translate the above into real code. But I'll be happy to help if you need further guidance.

Are there any illegal characters in MySQL which may not be stored in a field?

I'm looking for a shorthand solution to storing an md5 hash inside of a MySQL table, as string data. I had the idea that base256 could reduce the length of the string by half, down to a 16 digit string instead of 32 digits of hex. So I take hex and divide it up into chunks of two digits programatically then convert each set of two digits to ASCII. For example:
4cf5f5941a02573dc007e60442f5358a
is shortened to
Lõõ”W=ÀæBõ5Š
and it's OK if these characters don't print properly - I just need to store them. Would MySQL accept that sort of ASCII data into a text field without complaining?
MySQL will accept these values, but you must be very carefull when writing them - I strongly suggest binding parameters.
You might want to look into COMPRESS() and UNCOMPRESS() as an alternative:
INSERT INTO ... SET hashcode=COMPRESS('4cf5f5941a02573dc007e60442f5358a');
and
SELECT UNCOMPRESS(hashcode) AS hashcode FROM ... WHERE
might do the trick more readable

Can MySQL VARCHAR's store any chars?

Can MySQL VARCHAR's store any char like nulls and newlines?
MySQL can store any chars, but depending on the specified encoding, some characters may be misrepresented if different from your display encoding.
Varchars can contain any chars, even 0x00, since its not a null terminated string, but a length specified string, where the length is specified at the beginning of the string as a 2 or 4 byte value.
I'm not sure about Char columns, but I'm guessing they are null terminated in the sense that the first 0x00 indicates end of string (though storage still takes up the full length).
If you want to store true byte data though, you should use the BLOB type. That is also a length specified type, which is guaranteed to contain whatever data you put into it, and is not affected by encodings at all.
You should probably use the BINARY and VARBINARY data types for storing strings of non-printable characters, especially if you want strings of single bytes instead of actual text characters (which can be multi-byte).