Calculate decimal value related to 4 byte hex array - math

I am looking through a field of bytes with hex values. The first 4 bytes map to one real-Value, a number. Now I need to know what decimal value it stands for and how to get this information?
ByteA = '12'; that means '18' in dec;
ByteB = '01'; that means '1' in dec;
ByteC = '00'; that means '0' in dec;
ByteD = '00'; that means '0' in dec;

Each byte gets multiplied by 256 ^ the position in the field, so it could be either:
Big-endian (most significant byte first)
18 * 256 ^ 3 = 301,989,888
1 * 256 ^ 2 = 65,536
0 * 256 ^ 1 = 0
0 * 256 ^ 0 = 0
-----------
302,055,424
Little-endian:
0 * 256 ^ 3 = 0
0 * 256 ^ 2 = 0
1 * 256 ^ 1 = 256
18 * 256 ^ 0 = 18
-----------
274
Most programming languages have built-in hex to decimal capabilities.

Related

How to switch between radians and degrees in SAS

just looking for an easy way to run trig functions in SAS without having to manually correct in each calculation. Below is what I am working with.
I am running this in SAS 9 probably, the SAS Studio Student Module but this is a general SAS question.
I have manually created a variable, 'rad' in the 'calc' data step to deal with this but it adds a step of complexity that I would like to avoid.
I am asking whether there is a system setting, alternate trig function or ... ? that would change the calculation from:
bh_x = cos(rad*bh_a)*bh_l ;
to:
bh_x = cos(bh_a)*bh_l ;
so I don't have to manually convert my angle in degrees to radians for the trig function to work.
Thanks to anyone reading this and putting any mental effort to the solution!
Tim
data spec ;
length
b2h_a 8
b2h_l 8
b2h_l_e 8
bike $ 8
name $ 16
;
input
bike $
name $
bh_a
bh_l
ht_a
spcr
st_h
st_a
st_l
hb_r
hb_a
;
datalines ;
srcn (0,0) 0 0 67 0 0 0 0 0 0
srcn c 41 658 71.5 27 40 25 120 100 13
srcn ne_27_n13 41 658 71.5 27 40 27 127 100 13
srcn ne_15_0 41 658 71.5 15 40 27 127 100 0
srcn ne_5_0 41 658 71.5 5 40 27 127 100 0
srcn ne_2_n9 41 658 71.5 2 40 27 127 100 9
srcn ne_5_10 41 658 71.5 5 40 27 127 100 -10
srcn ne_10_rf10 41 658 71.5 10 40 27 127 20 -10
srcn max 41 658 90 250 0 0 250 0 0
;
run ;
data calc ;
set spec ;
pi=constant('pi') ;
rad=pi/180 ;
bh_x = cos(rad*bh_a)*bh_l ;
bh_y = sin(rad*bh_a)*bh_l ;
sr_x = (cos(rad*ht_a)*(spcr+st_h/2))*-1 ;
sr_y = sin(rad*ht_a)*(spcr+st_h/2);
st_x = cos(rad*(90-ht_a+st_a))*st_l ;
st_y = sin(rad*(90-ht_a+st_a))*st_l ;
hb_x = cos(rad*(90-hb_a))*hb_r*-1 ;
hb_y = sin(rad*(90-hb_a))*hb_r ;
hd_x = bh_x + sr_x + st_x + hb_x ;
hd_y = bh_y + sr_y + st_y + hb_y ;
if hd_x=0 then do ;
b2h_a=0 ;
b2h_l=0 ;
end ;
else do ;
b2h_a = atan(hd_y/hd_x)/rad ;
b2h_l = hd_y/sin(b2h_a*rad) ;
end ;
b2h_l_e = b2h_l/25.4 ;
drop pi rad ;
format
b2h_a 5.
b2h_l 5.
b2h_l_e 5.
bh_a 5.
bh_l 5.
ht_a 5.
spcr 5.
st_h 5.
st_a 5.
st_l 5.
hb_r 5.
hb_a 5.
bh_x 5.
bh_y 5.
sr_x 5.
sr_y 5.
st_x 5.
st_y 5.
hb_x 5.
hb_y 5.
hd_x 5.
hd_y 5.
b2h_a 5.
b2h_l 5.
b2h_l_e 5.1
;
run ;
There are no trig functions in SAS that accept DEGREE or GRADIAN arguments. You always need to convert from your data's angular measurement system to RADIAN.
You can write a macro to perform the conversion. Example:
%macro cosD(theta);
%* theta is angle in degrees;
%* emit data step source code that performs conversion from degrees to radians;
cos(&theta*constant('PI')/180)
%mend;
In use:
data calc ;
set spec ;
bh_x = %cosD(bh_a) * bh_l ;
You could convert the angular data to radians during the step where input occurs and then not have to worry about it again.

15 Hex in Binary form, explanation required?

I really really really can't understand how 15hex converted in Binary form gives me 10101bin.
That should be easy but I can't get it 😰
0x15 == 1*16 + 5*1 == 21
21 == 1*16 + 0*8 + 1*4 + + 0*2 + 1*1 == 10101 (binary)
What's not to love?
Well it's simple. In decimal base, number 15 means
10 + 5, because the number 1 means 1 * 10, and number 5 means 5 * 1.
And in hex, number 15 means:
1 * 16 + 5 * 1, meaning its 21. 21 in binary is 10101.
How to convert hex to binary
Convert each hex digit to 4 binary digits according to this table:
Hex Binary
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111
Example #1
Convert (4E)16 to binary:
(4)16 = (0100)2
(E)16 = (1110)2
So
(4E)16 = (01001110)2
Example #2
Convert(4A01)16 to binary:
(4)16 = (0100)2
(A)16 = (1010)2
(0)16 = (0000)2
(1)16 = (0001)2
So
(4A01)16 = (0100101000000001)2

How do I make big.mark apply to more than just the first column?

Here's what I'm getting:
> panderOptions('big.mark', ',')
> foo <- rbind(cancer, cancer); for(i in 1:8) foo <- rbind(foo, foo)
> pander(table(foo$ph.karno, foo$pat.karno))
-----------------------------------------------------
30 40 50 60 70 80 90 100
--------- ----- ---- ---- ---- ---- ----- ----- -----
**50** 0 512 512 512 512 512 0 0
**60** 0 512 512 2560 4608 1536 0 0
**70** 1,024 0 1024 4608 3072 3072 1536 1536
**80** 0 0 0 6144 6656 6656 10240 4608
**90** 0 0 0 1536 5120 10752 12288 7680
**100** 0 0 0 0 512 3584 6656 4096
-----------------------------------------------------
I would like the comma delimiter to show up in the other columns too. How do I do that?
Best result I got (with t being your table call result):
> pander(format(t,big.mark=','))
----------------------------------------------------------
30 40 50 60 70 80 90 100
--------- ----- ---- ----- ----- ----- ------ ------ -----
**50** 0 512 512 512 512 512 0 0
**60** 0 512 512 2,560 4,608 1,536 0 0
**70** 1,024 0 1,024 4,608 3,072 3,072 1,536 1,536
**80** 0 0 0 6,144 6,656 6,656 10,240 4,608
**90** 0 0 0 1,536 5,120 10,752 12,288 7,680
**100** 0 0 0 0 512 3,584 6,656 4,096
----------------------------------------------------------
I assume this is a bug in pander.table.return but I did not dig enough to get the root cause.
Edit: I found the reason, line 283 of the function there's a for loop calling sapply on each col, but once the first column has been processed, the full array of the table is converted to char as we bring in chars from the output of format.
Then the subsequent calls to format can't format the number as they've been coerced to char.
Code from pander.table.return giving this behavior:
for (j in 1:ncol(t)) {
temp.t[, j] <- sapply(temp.t[, j], format, trim = TRUE,
digits = digits[j], decimal.mark = decimal.mark,
big.mark = big.mark)
}

if 13* D = 1 mod 60 then D = 37 how?

I am solving an example problem, RSA algorithm
I have been given two prime numbers 7 and 11. Let's say p=7 and q=11
I have to calculate the decryption key, d, for some encryption key, e.
Firstly I calculated n=p*q which implies that n=77.
Suppose that e=13,
to calculate d I used the formula d*e = 1 mod fi,
where fi=(p-1)(q-1), and so fi=60
The final equation becomes 13*d = 1 mod fi
According to some solved example
d is calculated to be 37, how is this result obtained?
Any help would be appreciated.
i think this is what you are looking for
Verifying the answer is easy, finding it in the first place, a little more work.
Verification:
13 * 37 = 481
481 = 8 * 60 + 1
Hence if you divide 13 * 37 by 60 you have remainder 1.
Alternate answers:
Any integer of the form (37 + 60 k) where k is any integer is also a solution. (97, -23, etc.)
To find the solution you can proceed as follows:
Solve:
13 d = 1 + 60 k
mod 13:
0 = 1 + 8k (mod 13)
8k = -1 (mod 13)
Add 13's until a multiple of 8 is found:
8k = 12 or 25 or 38 or 51 or 64 .... aha a multiple of 8!
k = 64 / 8 = 8
Substitute k = 8 back into 13 d = 1 + 60 k
13 d = 1 + 8 * 60 = 481
481 /13 = 37
and that is the answer.
Use the extended Euclidean algorithm to compute integers x and y such that
13*x+60*y=1
Then x is the answer you're looking for, mod 60.

How to calculate modulus of large numbers?

How to calculate modulus of 5^55 modulus 221 without much use of calculator?
I guess there are some simple principles in number theory in cryptography to calculate such things.
Okay, so you want to calculate a^b mod m. First we'll take a naive approach and then see how we can refine it.
First, reduce a mod m. That means, find a number a1 so that 0 <= a1 < m and a = a1 mod m. Then repeatedly in a loop multiply by a1 and reduce again mod m. Thus, in pseudocode:
a1 = a reduced mod m
p = 1
for(int i = 1; i <= b; i++) {
p *= a1
p = p reduced mod m
}
By doing this, we avoid numbers larger than m^2. This is the key. The reason we avoid numbers larger than m^2 is because at every step 0 <= p < m and 0 <= a1 < m.
As an example, let's compute 5^55 mod 221. First, 5 is already reduced mod 221.
1 * 5 = 5 mod 221
5 * 5 = 25 mod 221
25 * 5 = 125 mod 221
125 * 5 = 183 mod 221
183 * 5 = 31 mod 221
31 * 5 = 155 mod 221
155 * 5 = 112 mod 221
112 * 5 = 118 mod 221
118 * 5 = 148 mod 221
148 * 5 = 77 mod 221
77 * 5 = 164 mod 221
164 * 5 = 157 mod 221
157 * 5 = 122 mod 221
122 * 5 = 168 mod 221
168 * 5 = 177 mod 221
177 * 5 = 1 mod 221
1 * 5 = 5 mod 221
5 * 5 = 25 mod 221
25 * 5 = 125 mod 221
125 * 5 = 183 mod 221
183 * 5 = 31 mod 221
31 * 5 = 155 mod 221
155 * 5 = 112 mod 221
112 * 5 = 118 mod 221
118 * 5 = 148 mod 221
148 * 5 = 77 mod 221
77 * 5 = 164 mod 221
164 * 5 = 157 mod 221
157 * 5 = 122 mod 221
122 * 5 = 168 mod 221
168 * 5 = 177 mod 221
177 * 5 = 1 mod 221
1 * 5 = 5 mod 221
5 * 5 = 25 mod 221
25 * 5 = 125 mod 221
125 * 5 = 183 mod 221
183 * 5 = 31 mod 221
31 * 5 = 155 mod 221
155 * 5 = 112 mod 221
112 * 5 = 118 mod 221
118 * 5 = 148 mod 221
148 * 5 = 77 mod 221
77 * 5 = 164 mod 221
164 * 5 = 157 mod 221
157 * 5 = 122 mod 221
122 * 5 = 168 mod 221
168 * 5 = 177 mod 221
177 * 5 = 1 mod 221
1 * 5 = 5 mod 221
5 * 5 = 25 mod 221
25 * 5 = 125 mod 221
125 * 5 = 183 mod 221
183 * 5 = 31 mod 221
31 * 5 = 155 mod 221
155 * 5 = 112 mod 221
Therefore, 5^55 = 112 mod 221.
Now, we can improve this by using exponentiation by squaring; this is the famous trick wherein we reduce exponentiation to requiring only log b multiplications instead of b. Note that with the algorithm that I described above, the exponentiation by squaring improvement, you end up with the right-to-left binary method.
a1 = a reduced mod m
p = 1
while (b > 0) {
if (b is odd) {
p *= a1
p = p reduced mod m
}
b /= 2
a1 = (a1 * a1) reduced mod m
}
Thus, since 55 = 110111 in binary
1 * (5^1 mod 221) = 5 mod 221
5 * (5^2 mod 221) = 125 mod 221
125 * (5^4 mod 221) = 112 mod 221
112 * (5^16 mod 221) = 112 mod 221
112 * (5^32 mod 221) = 112 mod 221
Therefore the answer is 5^55 = 112 mod 221. The reason this works is because
55 = 1 + 2 + 4 + 16 + 32
so that
5^55 = 5^(1 + 2 + 4 + 16 + 32) mod 221
= 5^1 * 5^2 * 5^4 * 5^16 * 5^32 mod 221
= 5 * 25 * 183 * 1 * 1 mod 221
= 22875 mod 221
= 112 mod 221
In the step where we calculate 5^1 mod 221, 5^2 mod 221, etc. we note that 5^(2^k) = 5^(2^(k-1)) * 5^(2^(k-1)) because 2^k = 2^(k-1) + 2^(k-1) so that we can first compute 5^1 and reduce mod 221, then square this and reduce mod 221 to obtain 5^2 mod 221, etc.
The above algorithm formalizes this idea.
To add to Jason's answer:
You can speed the process up (which might be helpful for very large exponents) using the binary expansion of the exponent. First calculate 5, 5^2, 5^4, 5^8 mod 221 - you do this by repeated squaring:
5^1 = 5(mod 221)
5^2 = 5^2 (mod 221) = 25(mod 221)
5^4 = (5^2)^2 = 25^2(mod 221) = 625 (mod 221) = 183(mod221)
5^8 = (5^4)^2 = 183^2(mod 221) = 33489 (mod 221) = 118(mod 221)
5^16 = (5^8)^2 = 118^2(mod 221) = 13924 (mod 221) = 1(mod 221)
5^32 = (5^16)^2 = 1^2(mod 221) = 1(mod 221)
Now we can write
55 = 1 + 2 + 4 + 16 + 32
so 5^55 = 5^1 * 5^2 * 5^4 * 5^16 * 5^32
= 5 * 25 * 625 * 1 * 1 (mod 221)
= 125 * 625 (mod 221)
= 125 * 183 (mod 183) - because 625 = 183 (mod 221)
= 22875 ( mod 221)
= 112 (mod 221)
You can see how for very large exponents this will be much faster (I believe it's log as opposed to linear in b, but not certain.)
/* The algorithm is from the book "Discrete Mathematics and Its
Applications 5th Edition" by Kenneth H. Rosen.
(base^exp)%mod
*/
int modular(int base, unsigned int exp, unsigned int mod)
{
int x = 1;
int power = base % mod;
for (int i = 0; i < sizeof(int) * 8; i++) {
int least_sig_bit = 0x00000001 & (exp >> i);
if (least_sig_bit)
x = (x * power) % mod;
power = (power * power) % mod;
}
return x;
}
5^55 mod221
= ( 5^10 * 5^10 * 5^10 * 5^10 * 5^10 * 5^5) mod221
= ( ( 5^10) mod221 * 5^10 * 5^10 * 5^10 * 5^10 * 5^5) mod221
= ( 77 * 5^10 * 5^10 * 5^10 * 5^10 * 5^5) mod221
= ( ( 77 * 5^10) mod221 * 5^10 * 5^10 * 5^10 * 5^5) mod221
= ( 183 * 5^10 * 5^10 * 5^10 * 5^5) mod221
= ( ( 183 * 5^10) mod221 * 5^10 * 5^10 * 5^5) mod221
= ( 168 * 5^10 * 5^10 * 5^5) mod221
= ( ( 168 * 5^10) mod 221 * 5^10 * 5^5) mod221
= ( 118 * 5^10 * 5^5) mod221
= ( ( 118 * 5^10) mod 221 * 5^5) mod221
= ( 25 * 5^5) mod221
= 112
What you're looking for is modular exponentiation, specifically modular binary exponentiation. This wikipedia link has pseudocode.
Chinese Remainder Theorem comes to mind as an initial point as 221 = 13 * 17. So, break this down into 2 parts that get combined in the end, one for mod 13 and one for mod 17. Second, I believe there is some proof of a^(p-1) = 1 mod p for all non zero a which also helps reduce your problem as 5^55 becomes 5^3 for the mod 13 case as 13*4=52. If you look under the subject of "Finite Fields" you may find some good results on how to solve this.
EDIT: The reason I mention the factors is that this creates a way to factor zero into non-zero elements as if you tried something like 13^2 * 17^4 mod 221, the answer is zero since 13*17=221. A lot of large numbers aren't going to be prime, though there are ways to find large primes as they are used a lot in cryptography and other areas within Mathematics.
This is part of code I made for IBAN validation. Feel free to use.
static void Main(string[] args)
{
int modulo = 97;
string input = Reverse("100020778788920323232343433");
int result = 0;
int lastRowValue = 1;
for (int i = 0; i < input.Length; i++)
{
// Calculating the modulus of a large number Wikipedia http://en.wikipedia.org/wiki/International_Bank_Account_Number
if (i > 0)
{
lastRowValue = ModuloByDigits(lastRowValue, modulo);
}
result += lastRowValue * int.Parse(input[i].ToString());
}
result = result % modulo;
Console.WriteLine(string.Format("Result: {0}", result));
}
public static int ModuloByDigits(int previousValue, int modulo)
{
// Calculating the modulus of a large number Wikipedia http://en.wikipedia.org/wiki/International_Bank_Account_Number
return ((previousValue * 10) % modulo);
}
public static string Reverse(string input)
{
char[] arr = input.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
Jason's answer in Java (note i < exp).
private static void testModulus() {
int bse = 5, exp = 55, mod = 221;
int a1 = bse % mod;
int p = 1;
System.out.println("1. " + (p % mod) + " * " + bse + " = " + (p % mod) * bse + " mod " + mod);
for (int i = 1; i < exp; i++) {
p *= a1;
System.out.println((i + 1) + ". " + (p % mod) + " * " + bse + " = " + ((p % mod) * bse) % mod + " mod " + mod);
p = (p % mod);
}
}
Just provide another implementation of Jason's answer by C.
After discussing with my classmates, based on Jason's explanation, I like the recursive version more if you don't care about the performance very much:
For example:
#include<stdio.h>
int mypow( int base, int pow, int mod ){
if( pow == 0 ) return 1;
if( pow % 2 == 0 ){
int tmp = mypow( base, pow >> 1, mod );
return tmp * tmp % mod;
}
else{
return base * mypow( base, pow - 1, mod ) % mod;
}
}
int main(){
printf("%d", mypow(5,55,221));
return 0;
}
This is called modular exponentiation(https://en.wikipedia.org/wiki/Modular_exponentiation).
Let's assume you have the following expression:
19 ^ 3 mod 7
Instead of powering 19 directly you can do the following:
(((19 mod 7) * 19) mod 7) * 19) mod 7
But this can take also a long time due to a lot of sequential multipliations and so you can multiply on squared values:
x mod N -> x ^ 2 mod N -> x ^ 4 mod -> ... x ^ 2 |log y| mod N
Modular exponentiation algorithm makes assumptions that:
x ^ y == (x ^ |y/2|) ^ 2 if y is even
x ^ y == x * ((x ^ |y/2|) ^ 2) if y is odd
And so recursive modular exponentiation algorithm will look like this in java:
/**
* Modular exponentiation algorithm
* #param x Assumption: x >= 0
* #param y Assumption: y >= 0
* #param N Assumption: N > 0
* #return x ^ y mod N
*/
public static long modExp(long x, long y, long N) {
if(y == 0)
return 1 % N;
long z = modExp(x, Math.abs(y/2), N);
if(y % 2 == 0)
return (long) ((Math.pow(z, 2)) % N);
return (long) ((x * Math.pow(z, 2)) % N);
}
Special thanks to #chux for found mistake with incorrect return value in case of y and 0 comparison.

Resources