Sybase data conversion - sybase-ase

I have a char(32) column that store a hexadecimal. I need to convert this hex number to decimal say decimal(40,0) since An unsigned bigint can't be enough to hold this 32 char long hex. I can't find a way to do this convention , hex to decimal.
Anyone please help and thank you in advance!
Db
Sorry, this is in Sybase ase 15

not the most elegant solution
- would be better to use a loop instead of repeated lines of code
- or even just reduce the lines by using blocks of 4-character substring, instead of 1 character at a time
also this solution assumes hexadecimal strings are completely filled (if they are blank-padded, some additional gymnastics would have to be performed to parse the string up and get the bytes into the correct buckets)
but fundamentally, this is the idea:
create variable h varchar(32);
set h = 'FEDCBA9876543210FEDCBA9876543210';
create variable a decimal(40,0);
set a =
hextoint(substr(h,1,1))*power(16,31)+
hextoint(substr(h,2,1))*power(16,30)+
hextoint(substr(h,3,1))*power(16,29)+
hextoint(substr(h,4,1))*power(16,28)+
hextoint(substr(h,5,1))*power(16,27)+
hextoint(substr(h,6,1))*power(16,26)+
hextoint(substr(h,7,1))*power(16,25)+
hextoint(substr(h,8,1))*power(16,24)+
hextoint(substr(h,9,1))*power(16,23)+
hextoint(substr(h,10,1))*power(16,22)+
hextoint(substr(h,11,1))*power(16,21)+
hextoint(substr(h,12,1))*power(16,20)+
hextoint(substr(h,13,1))*power(16,19)+
hextoint(substr(h,14,1))*power(16,18)+
hextoint(substr(h,15,1))*power(16,17)+
hextoint(substr(h,16,1))*power(16,16)+
hextoint(substr(h,17,1))*power(16,15)+
hextoint(substr(h,18,1))*power(16,14)+
hextoint(substr(h,19,1))*power(16,13)+
hextoint(substr(h,20,1))*power(16,12)+
hextoint(substr(h,21,1))*power(16,11)+
hextoint(substr(h,22,1))*power(16,10)+
hextoint(substr(h,23,1))*power(16,9)+
hextoint(substr(h,24,1))*power(16,8)+
hextoint(substr(h,25,1))*power(16,7)+
hextoint(substr(h,26,1))*power(16,6)+
hextoint(substr(h,27,1))*power(16,5)+
hextoint(substr(h,28,1))*power(16,4)+
hextoint(substr(h,29,1))*power(16,3)+
hextoint(substr(h,30,1))*power(16,2)+
hextoint(substr(h,31,1))*power(16,1)+
hextoint(substr(h,32,1))*power(16,0);

Related

What data type should use in a MySQL database to store 2 text files of code. If I intend to compare similarity later

What data type should use in a MySQL database to store 2 text files of code. If I intend to compare similarity later.
It's a MySQL database running on my Windows machine.
Also can you recommend an API that can compare code for me.
As per MySQL documentation
Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 65,535. The effective maximum length of a VARCHAR is subject to the maximum row size (65,535 bytes, which is shared among all columns) and the character set used.
...
Values in CHAR and VARCHAR columns are sorted and compared according to the character set collation assigned to the column.
So, VARCHAR is stored inline with the table, whilst BLOB and TEXT types are stored off the table with the database holding the location of the data. Depending on how long your text is, TEXT might be defined as TINYTEXT, TEXT, MEDIUMTEXT, and LONGTEXT, the only difference is the maximum amount of data it holds.
TINYTEXT 256 bytes
TEXT 65,535 bytes
MEDIUMTEXT 16,777,215 bytes
LONGTEXT 4,294,967,295 bytes
To compare the two strings stored in TEXT (or any other string column) you might want to use STRCMP(expr1,expr2)
STRCMP() returns 0 if the strings are the same, -1 if the first argument is smaller than the second according to the current sort order, and 1 otherwise.
If you specify the desired output of the comparison, I might edit the answer.
EDIT
To compare two strings and calculate the difference percentage, you might want to use similar_text. As the official documentation states:
This calculates the similarity between two strings as described in Programming Classics: Implementing the World's Best Algorithms by Oliver (ISBN 0-131-00413-1). Note that this implementation does not use a stack as in Oliver's pseudo code, but recursive calls which may or may not speed up the whole process. Note also that the complexity of this algorithm is O(N**3) where N is the length of the longest string.

Most space efficient way to store large integer from php to mysql?

I'm working with integers greater up to 128 bits long. They're used to store a large set of flags and I don't need to do any weird math with them, so I can treat it like a string in php to get around the PHP_INT_MAX limit.
I think want to store these numbers in a BINARY column in mysql. The column will need between 4-16 bytes to hold the numbers.
My understanding is that the BINARY column in php is a binary string, does this mean I'll be wasting space by not using a-z as part of the character set? Should I be using a different type of column? Do I need to base_convert in php to get the full use of the character set?
How do I get my string representation of a 128 bit integer in php stored the most efficiently into a 128 bit column in php?
Also, if roughly half of the integers I'm storing with only need 4 bytes, would I be better off using a VARBINARY column?
Assuming you will be using the full range of 128 bits, each number equally likely, the most space-efficient you can be is storing 128/8 = 16 chars per number.
Conversion between this binary representation and a PHP string is a little problematic though. To decode a binary string into a base-16 number you can use unpack:
$numberInHex = unpack("H*", $binaryData);
If you must convert the output to or from decimal numbers you'll have to use gmp or bc.
Update: An example:
> create table binary_test ( int128 binary(16) );
> insert into binary_test set int128 = 0x11223344556677889900112233445566;
> select hex(int128) from binary_test;
+----------------------------------+
| hex(int128) |
+----------------------------------+
| 11223344556677889900112233445566 |
+----------------------------------+
Instead of 0x1122... you could also use unhex('1122..').
If you save the integers in binary format (example: 45 -> 00101101(bin), 0x2D(hex)) you would not waste any space, because you would not use characters but bits.
As always it depends how much data you have. If you are talking about a few thousand numbers, you don't need to worry about varbinary. On the other hand, if you have a few million/billion records then it is worth doing some optimizations.

Create a unique 4-byte Integer number from a String in PHP

I Have SQL table wich uses strings for a key. I need to convert that string (max. 18 Characters) to a unique (!) 4-byte integer using PHP. Can anyone help?
Unique? Not possible, sorry.
Let's take a closer look:
With 18 characters, even if we were assuming only the 128 possible characters of ASCII (7 bits), you'd get 128^18 possible strings (and I'm not even going into the possibility of shorter strings!), which is about 8E37 ( 8 and 37 zeroes ).
With a 4-byte integer, you're getting 256^4 possible integers, which is about 4E9 ( 4 billion ).
So, you have about 4E28 more strings than you have integers; you can't have an unique mapping.
Therefore, you'll definitely run into a collision as soon as you enter the 4294967297th key, but it is possible to run into one as soon as you enter more than one.
See also: http://en.wikipedia.org/wiki/Pigeonhole_principle
Keep a lookup-table of strings to integers. Everytime you encounter a new string you add it to the mapping table and assign it a new unique ID. This will work for about 2^32 strings which is probably enough.
There is no way to do this for more that 2^32 distinct strings.
You can't. A four-byte integer can represent 2^32 = 4 billion values, which is not enough to hold your target space.
If you currently have less then 4 billion rows in the table, you could create a cross table that just assigns an incremental value to each. You'd be limited to 4 billion rows with this approach, but this may be fine for your situation.

64-bit Password Hashes in MySQL tables

I use this function for hashing my passwords:
// RETURNS: rAyZOnlNBxO2WA53z2rAtFlhdS+M7kec9hskSCpeL6j+WwcuUvfFbpFJUtHvv7ji
base64_encode(hash_hmac('sha384', $str . SC_NONCE, SC_SITEKEY, true));
And I store hashes in char(64) field (MySQL -InnoDB).
Should I use varchar(64) instead of char(64)? Why?
Edit:
I changed sha256 with sha384. Because in this example, sha256 always returns 44 bytes for me. Sorry for confusing. Now it's 64-bytes.
varchars save storage by only using up to the length required. If the 64 bit hash is always 64 then it makes no difference in terms of storage so probably char is just as good as varchar in this case.
If you have variable length data to store, then a varchar will save wasting unnecessary space.
You should use CHAR(64) since your hash is fixed in length. Using VARCHAR will add another byte, wasting space.
One of the alternative ways you can do that (if you actually care much about space) is to store the hash in the binary form. Some details of how to do that may be found here; you'd probably want BINARY(32) for a SHA-256 hash.
Even though you are using a Base 64 encoded string, the result is not necessarily 64 bits in length. In this case, VARCHAR is better because the result can be shorter than 64 bits.
In fact as seen here, 64 bits is the maximum length rather than the set length.

Storing something as unsigned tinyint in php

Is there a way to explicitly store my numbers in php as tinyint (1 byte instead of 4).
Or could i only enforce this by storing them 4 by 4 in an int? (using a few binary operations)
I generate these values by breaking a string using str_split and interpretting these bytes as ints via unpack( 'C' , .. ).
Currently i store these values in an array as invdividual integers but it could save alot of space if i could store them somehow as tinyints.
PHP has two data types that you may want to use here: integer and string.
PHP doesn't have any other types you could choose from (float wouldn't be a good choice for integers, the other types are not appropriate).
An int is usually 32 or 64 bits, a string is 1 byte per character.* I propose that unless you have a lot of numbers, you won't ever see any problem with 32 bit ints. If you absolutely positively want to safe space memory** and your numbers have a maximum of 3 digits, you could handle your numbers as strings. There's even the BCMath extension that'll let you operate on string numbers directly without needing to cast them back and forth. It's quite a lot of hassle for possibly very limited gain though.
Seeing that a MySQL TINYINT is usually used for boolean values though, please be aware PHP does have a boolean type...!
* One byte per one-byte character, that is.
** Since PHP scripts are usually only very temporary, you should only have problems with peak memory usage, not storage space. Getting more RAM may be the more efficient solution than playing with types.

Resources