Converting a positive whole number of length 12 to a unique alphanumeric of length 10 - radix

Would it be ok to do this by base conversion from base 10? If so, which would be the best base to convert to in order to restrict the length of the generated string to 10 characters maximum?
Thanks

Hexadecimal would suit your neeeds.
The largest 12 digit number 999999999999 in hexadecimal is e8d4a50fff which is only ten characters.

The biggest 12-character number in base 10 is 999 999 999 999.
A little snippet in ruby shows that the smallest base you can use to be sure to have a 10-character string is base 16, or hexadecimal:
1.9.3-p194 :044 > 999999999999.to_s(15)
=> "1b02b766469"
1.9.3-p194 :045 > 999999999999.to_s(15).length
=> 11
1.9.3-p194 :046 > 999999999999.to_s(16)
=> "e8d4a50fff"
1.9.3-p194 :047 > 999999999999.to_s(16).length
=> 10

Related

unknown non-binary data encoding - any hints?

I' trying to decode data sent via RF by a weather station.
Unfortunately, the data representation isn't in standard binary way (0000, 0001, 0010, 0011, ...). What I've found is the following scheme:
value representation
0 => 0xff = 0b11111111
1 => 0x00 = 0b00000000
2 => 0x01 = 0b00000001
3 => 0xfe = 0b11111110
4 => 0x03 = 0b00000011
5 => 0xfc = 0b11111100
6 => 0xfd = 0b11111101
7 => 0x02 = 0b00000010
...
Or broken down to the bits:
value: 0 8 16 24
| | | |
Bit 0: 1010101010101010101010101010 ...
Bit 1: 1001100110011001100110011001
Bit 2: 1001011010010110100101101001
Bit 3: 1001011001101001100101100110
Bit 4: 1001011001101001011010011001
Bit 5: 1001011001101001011010011001
Bit 6: 1001011001101001011010011001
Bit 7: 1001011001101001011010011001
Each bit seems to follow a certain pattern of mirroring and inversion of the preceding, e.g. bit 3 = 10 01 0110 01101001
What is that kind of encoding called like, and how to easily convert it to a standard binary form?
It looks like the LSB pattern is periodic with period 2 (10 repeated), the next bit is periodic with period 4 (1001 repeated), and presumably the bit before that has period 8 (10010110 repeated).
This is somewhat similar to the normal representation, of course, except that usually the repeating patterns are 01, 0011, 00001111 etcetera.
It seems the pattern 1001 is created by copying 10 and inverting the second copy. Similarly, the pattern 100100110 is created by copying and inverting 1001. Hence, the next pattern of period 16 would be 10010011001101001.
Now, how are these patterns related?
For the lowest bit, 10 repeated is 01 repeated XOR (11). Simple.
For the next bit, 1001 repeated is 0011 XOR (1010) repeated - and note that the LSB pattern was 10 repeated.
After that, we get 10010110 repeated which is 00001111 XOR (10011001) repeated. See the pattern?
So: You need to XOR each bit with the bit to its right, starting from the MSB.

Does 2's representation of a positive number exist?

CASE 1:
Let me try to represent -7 in 2's complement in 4 bits:-
7 in binary : 0111
7 in 1's complement:1000
7 in 2's complement:1001
So converting my 2's number to decimal: -1x2^3+0+0+1x2^0
=> -8+1=-7
its correct !!!
CASE 2:
Let me try to represent 7 in 2's complement in 4 bits:-
-7 in binary : 1111
7 in 1's complement:1000
7 in 2's complement:1001
So converting my 2's number to decimal: -1x2^3+0+0+1x2^0
=> -8+1=-7
its still -7 and i am wrong!!!!
You have slightly mixed up the concepts -
MSB(Most significant bit) represents sign of a number. Where 0 stands for positive and 1 stands for negative. Also, MSB do not participate in number conversions (if its representing sign).
Hence, -7 in binary is 1111 and not 0111.
Now, to do addition, subtraction, division, multiplication on binary numbers we can either use signed numbers with MSB and define a new est of rules to get the correct result.
OR
Use complements method to do it.
To calculate two's complement of a number
Invert all the bits (0111) -> (1000)
Add one to the result (1000 + 1) -> (1001)
+7 -> 0111
(+) -7 -> 1001 (2s complement)
......................
0 -> 10000 (ignoring the carry over MSB we will get zero which is the correct answer)

How do you put multiple values into one variable or field without using a list and then parsing?

Sometimes there is a need to have multiple values in one variable or database field, even though that violates relational normalization principles. In python and other languages that support lists, that's easy. In others it is not. See insert multiple values in single attribute
One common technique is to concatenate values into a comma delimited string: "1,2,3" or "English,French,Spanish" and then extracting values by parsing.
When the valid values come from an enumerated list, is there another way that does not require parsing?
Yes. Use prime numbers, multiply them together, then factor them out.
The field type to use is integer or large integer
Use code values that are prime numbers
3 == English
5 == French
7 == Spanish
11 == Italian
Store the product of all that apply into the field.
21 == English and Spanish
385 == French, Spanish and Italian
Use modulo functions to determine which values are in the field
if ( field % 3 == 0 ) { english() ;}
if ! (field % 5) { french() ;}
=IF(NOT(MOD(A203,5)),"French","")
The same value can appear multiple times
9 == English, English
I first used this technique to store dimensions.
3 == time
5 == length
7 == mass
11 == charge
13 == temperature
17 == moles
For example, a "first moment" lever-arm would have a dimension value of 35 == mass * length.
To store fractional dimensions in an integer, I multiplied fractional dimensions by the product of all of them and dealt with it in processing.
255255 == 3*5*7*11*13*17
force == mass * length / (second^2)
force == ( 7 * 5 / ( 3 * 3 ) ) * 255255 * 255255
force == 253381002875
The reason I used integers was to avoid dealing with invalid equality comparisons due to rounding errors.
Please do not ask for the code to extract the fractional dimensions. All this was 40 years ago in APL/360.
If you don't need to allow for multiples of the same value, then you could use a bit map. Depending on whether there are up to 8, 16, 32, 64, or 128 allowed values, they could fit in a 1, 2, 4, 8, or 16 byte integer.

binary to decimal in objective-c

I want to convert the decimal number 27 into binary such a way that , first the digit 2 is converted and its binary value is placed in an array and then the digit 7 is converted and its binary number is placed in that array. what should I do?
thanks in advance
That's called binary-coded decimal. It's easiest to work right-to-left. Take the value modulo 10 (% operator in C/C++/ObjC) and put it in the array. Then integer-divide the value by 10 (/ operator in C/C++/ObjC). Continue until your value is zero. Then reverse the array if you need most-significant digit first.
If I understand your question correctly, you want to go from 27 to an array that looks like {0010, 0111}.
If you understand how base systems work (specifically the decimal system), this should be simple.
First, you find the remainder of your number when divided by 10. Your number 27 in this case would result with 7.
Then you integer divide your number by 10 and store it back in that variable. Your number 27 would result in 2.
How many times do you do this?
You do this until you have no more digits.
How many digits can you have?
Well, if you think about the number 100, it has 3 digits because the number needs to remember that one 10^2 exists in the number. On the other hand, 99 does not.
The answer to the previous question is 1 + floor of Log base 10 of the input number.
Log of 100 is 2, plus 1 is 3, which equals number of digits.
Log of 99 is a little less than 2, but flooring it is 1, plus 1 is 2.
In java it is like this:
int input = 27;
int number = 0;
int numDigits = Math.floor(Log(10, input)) + 1;
int[] digitArray = new int [numDigits];
for (int i = 0; i < numDigits; i++) {
number = input % 10;
digitArray[numDigits - i - 1] = number;
input = input / 10;
}
return digitArray;
Java doesn't have a Log function that is portable for any base (it has it for base e), but it is trivial to make a function for it.
double Log( double base, double value ) {
return Math.log(value)/Math.log(base);
}
Good luck.

how to create unique integer number from 3 different integers numbers(1 Oracle Long, 1 Date Field, 1 Short)

the thing is that, the 1st number is already ORACLE LONG,
second one a Date (SQL DATE, no timestamp info extra), the last one being a Short value in the range 1000-100'000.
how can I create sort of hash value that will be unique for each combination optimally?
string concatenation and converting to long later:
I don't want this, for example.
Day Month
12 1 --> 121
1 12 --> 121
When you have a few numeric values and need to have a single "unique" (that is, statistically improbable duplicate) value out of them you can usually use a formula like:
h = (a*P1 + b)*P2 + c
where P1 and P2 are either well-chosen numbers (e.g. if you know 'a' is always in the 1-31 range, you can use P1=32) or, when you know nothing particular about the allowable ranges of a,b,c best approach is to have P1 and P2 as big prime numbers (they have the least chance to generate values that collide).
For an optimal solution the math is a bit more complex than that, but using prime numbers you can usually have a decent solution.
For example, Java implementation for .hashCode() for an array (or a String) is something like:
h = 0;
for (int i = 0; i < a.length; ++i)
h = h * 31 + a[i];
Even though personally, I would have chosen a prime bigger than 31 as values inside a String can easily collide, since a delta of 31 places can be quite common, e.g.:
"BB".hashCode() == "Aa".hashCode() == 2122
Your
12 1 --> 121
1 12 --> 121
problem is easily fixed by zero-padding your input numbers to the maximum width expected for each input field.
For example, if the first field can range from 0 to 10000 and the second field can range from 0 to 100, your example becomes:
00012 001 --> 00012001
00001 012 --> 00001012
In python, you can use this:
#pip install pairing
import pairing as pf
n = [12,6,20,19]
print(n)
key = pf.pair(pf.pair(n[0],n[1]),
pf.pair(n[2], n[3]))
print(key)
m = [pf.depair(pf.depair(key)[0]),
pf.depair(pf.depair(key)[1])]
print(m)
Output is:
[12, 6, 20, 19]
477575
[(12, 6), (20, 19)]