Convert decimal to byte array - c#

assume I have decimal X
I want to calculate 3 byte as a,b,c where a.bc Gig is near X.
I want it to be clean and as short as it possible.
I've already implement it but it is very bad but works.
for example X = 2972117368, I want a = 2, b = 7, c = 6 . how?
2972117368/(1024*1024*1024) = 2.76799999922514
X will be always lesser than 9.99 gigabyte.

Is seems like you're most of the way there:
decimal x = 2972117368;
double gig = Convert.ToDouble(x) / 1073741824.0;
byte a = (byte)Math.Floor(gig); // works for up to 127 gig - actually up to 256
byte b = (byte)(Math.Floor(gig * 10) % 10);
byte c = (byte)(Math.Floor(gig * 100) % 10);
Edited: For some typos & logical errors

Encoding.ASCII.GetBytes((double.Parse((X / (1024.0 * 1024 * 1024)).ToString("0.00")) * 100).ToString())

Related

private double always returning 0

I have this function:
private double getTotal(string str)
{
double total = 0;
byte[] asciiBytes = Encoding.ASCII.GetBytes(str);
foreach(int c in asciiBytes)
{
total = total + c;
total = total * (5 * (c ^ 2) / (c*6));
}
return Math.Round(total);
}
This is used to get a total of a strings ASCII values but does some math along the way rather than just adding. I need this to return the total, but is currently returning 0. How can I make it return the correct value? (PS: It needs to return an integer, but this can be in the datatype of a double for conversion later. Basically just need it to return a whole number.) (PSPS: I don't know what the string will be, it's up to the end user)
_
You probably misunderstood the ^ sign. It stands for a bitwise exclusive or, rather than an exponentiation. If you want to use the latter, use this:
total = total * (5 * (Math.Pow (c, 2) / (c * 6));
However, you could write it shorter/more beautiful/more efficient as well:
total *= (5 * (c * c) / (6 * c));
I replaced the Pow, as it is slower than a simple multiplication and used an assignment-operator.
Furthermore, the equation itself can be simplified:
total *= c * (5 / 6);
However, you should still mark the numbers as doubles, as 5/6 would result in 0 otherwise:
total *= c * (5.0 / 6.0)
For more information on exponentiation in C#, have a look at this.
By the way, the ^ sign takes every bit of the numbers and compares them. The new value will be 1 if the first bit or the second bit, but not both bits are 1.
So for example 0101 xor 1110 would result in 1011.
You have casting problem. The c variable is integer. Your problem is in the total = total * (5 * (c ^ 2) / (c*6)); expression.
Because the internal results (c ^ 2) and (c*6) aren't double, when the division result has floating point such as 0.nnnnn, the final result isn't double and you get only the 0 which is the real part of the number. And the result expression (5 * (c ^ 2) / (c*6)) as an Integer is 0. Finally the expression is as total=total * (0);
Use internal castings in your code
Replace your code with the following :
total = total * (5 * ((double)(c ^ 2)) / ((double)(c * 6)));
Please run the following code
static private double getTotal(string str)
{
double total = 0;
byte[] asciiBytes = Encoding.ASCII.GetBytes(str);
foreach (int c in asciiBytes)
{
double dC = c;
total = total + c;
double cXor2 = c ^ 2;
double c6 = c * 6;
double fiveCXor2 = 5 * cXor2;
double semiFinal = fiveCXor2 / c6;
double final = total * semiFinal;
Console.WriteLine("c = " + (c).ToString());
Console.WriteLine("c ^ 2 = " + (cXor2).ToString());
Console.WriteLine("c * 6 = " + (c6).ToString());
Console.WriteLine("5 * (c ^ 2) = " + (fiveCXor2).ToString());
Console.WriteLine("semi final = " + semiFinal);
Console.WriteLine("final = " + final);
Console.WriteLine("--------------------------------------------");
total = total * (5 * (c ^ 2) / (c * 6));
Console.WriteLine("TOTAL = " + total);
Console.WriteLine("--------------------------------------------");
}
return Math.Round(total);
}
Sample result is :
c = 97
c ^ 2 = 99
c * 6 = 582
5 * (c ^ 2) = 495
semi final = 0.850515463917526
final = 82.5
--------------------------------------------
TOTAL = 0
--------------------------------------------
c = 98
c ^ 2 = 96
c * 6 = 588
5 * (c ^ 2) = 480
semi final = 0.816326530612245
final = 80
--------------------------------------------
TOTAL = 0
--------------------------------------------
As you can see the problem is casting
Because the c variable is int the casting procedure is :
step 1
[double] = [double] * ([int] * ([int] ^ [int] ) / ([int] * [int] ))
total = total * (5 * (c ^ 2 ) / (c * 6 ));
step 2
[double] = [double] * ([int] * ([int]) / ([int] ))
total = total * (5 * (X) / (Y) );
step 3
[double] = [double] * ([int] * [int]))
total = total * (5 * XdivY );
**CASTING PROBLEM : In this step the XdivY is integer and when the result is 0.1234 the INT result is 0**
step 4
[double] = [double] * ([double]))
total = total * (5mulXdivY );
here c# casting the 5mulXdivY 0 to double but the result is zero
step 5
[double] = [double]
total = 0
Problem is with the this line in your code
total = total * (5 * (c ^ 2) / (c*6));
c ^ 2 returns a smaller value than c*6. Now the operator / is integer division so the result of a smallnumber/largenumber will always return zero. This will make the value of variable total zero in every iteration of the loop. Change the code like this and it will give you the result you expect.
private double getTotal(string str)
{
double total = 0;
byte[] asciiBytes = Encoding.ASCII.GetBytes(str);
foreach (int c in asciiBytes)
{
total = total + c;
total = total * (5 * (double)(c ^ 2) / (double)(c * 6));
}
return Math.Round(total);
}
Hope it helps.
Add double to one of the ints
private double getTotal(string str)
{
double total = 0;
byte[] asciiBytes = Encoding.ASCII.GetBytes(str);
foreach (int c in asciiBytes)
{
total = total + c;
total = total * ((double)5 * (c ^ 2) / (c * 6));
}
return Math.Round(total);
}

Double presentation and precision?

I've written following code in c++ :
double t = pow(pow(2, 32), 4)+5;
double div = floor(t / pow(2, 32));
double div2 = div*pow(2, 32);
double remain = t - div2;
cout << remain << endl;
the remain must be 5 but console and debugging show me 0.00000000 ??? why?
similar code in c#:
double t = Math.Pow(Math.Pow(2, 32), 4) + 5;
double div = Math.Floor(t / Math.Pow(2, 32));
double div2 = div * Math.Pow(2, 32);
double remain = t - div2;
Console.WriteLine(remain);
You are adding 5 to 2128 using double. For the addition of 5 to have any effect it would need to use, at least, 127 bits to represent the significant. It uses 52 if I recall correctly. You'd need to use a much bigger representation. Since you only do integer operations a big integer representation should do.
Your function overflows... Use BigInteger...
var t = BigInteger.Pow(BigInteger.Pow(2, 32), 4) + 5;
var div = t / BigInteger.Pow(2, 32);
var div2 = div * BigInteger.Pow(2, 32);
var remain = t - div2;
Console.WriteLine(remain);

How to calculate the modular multiplicative inverse for the Affine Cipher

I am trying to create a small software that does the Affine Cipher, which means that K1 and the amount of letters in the alphabet (using m for this number) must be coprime, that is gcd(k1, m) == 1.
Basically it's like this:
I have a plaintext: hey
I have K1: 7
I have K2: 5
Plaintext in numerical format is:
8 5 25
8 - from h (the position in the alphabet) and **
5 25** goes the same for e and y
Encrypted: 7 13 18
Which is the formula:
k1 * 8 + k2 mod 27 = 7
k1 * 5 + k2 mod 27 = 13
k1 * 25 + k2 mod 27 = 18
I have a function that crypts this but I don't know how to decrypt.
For example I have 7 for h. I want to get the number 8 back again, knowing 7, k1 and k2.
Do you guys have any ideas ?
Some function where you input k1, k2, result (7 for example, for h), and it gives me back 8, but I really don't know how to reverse this.
The function for encryption is this:
public List<int> get_crypted_char(string[] strr)
{
List<int> l = new List<int>();
int i;
for (i = 0; i < strr.Length; i++)
{
int ch = int.Parse(strr[i]);
int numberback = k1 * ch + 5;
numberback = (numberback % 27);
l.Add(numberback);
}
return l;
}
Where: string[] strr is a string that contains the plaintext.
Function example:
get_crypted_char({"e","c","b"})
The result would be a list like this {"5","3","2"}
UPDATE:
Here is a link from wikipedia about this encryption, and also decryption, but ... I don't really understand "how to"
http://en.wikipedia.org/wiki/Affine_cipher
It is not possible (in general case, for affine cipher, see update below). That's why module operation is so frequently used in security algorithms - it is not reversible. But, why don't we try?
result = (k1 * input + k2) % 27 (*1)
Let's take the first letter:
result = (7 * 8 + 5) % 27 = 7
That's cool. Now, because we said, that:
result = (k1 * input + k2) % 27
the following is also true:
k1 * input + k2 = 27 * div + result (*2)
where
div = (k1 * input + k2) / 27 (integral division)
It is quite obvious (if a % b = c, then a = b*n + c, where n is the result of integer division a/b).
You know the values of k1 (which is 7), k2 (5) and result (7). So, when we put these values to (*2), we get the following:
7 * input + 5 = 27 * div + 7 //You need to solve this
As you can see, it is impossible to solve this, because you would need to know also the result of the integral division - translating this to your function's language, you would need the value of
numberback / 27
which is unknown. So answer is: you cannot reverse your function's results, using only output it returns.
** UPDATE **
I focused too much on the question's title, so the answer above is not fully correct. I decided not to remove it, however, but write an update.
So, the answer for your particular case (affine cipher) is: YES, you can reverse it.
As you can see on the wiki, decryption function for affine cipher for the following encrytption function:
E(input) = a*input + b mod m
is defined as:
D(enc) = a^-1 * (enc - b) mod m
The only possible problem here can be computation of a^-1, which is modular multiplicative inverse.
Read about it on wiki, I will provide only example.
In your case a = k1 = 7 and m = 27. So:
7^-1 = p mod 27
7p = 1 mod 27
In other words, you need to find p, which satisfies the following: 7p % 27 = 1.
p can be computed using extended euclidean algorithm and I computed it to be 4 (4 * 7 = 28, 28 % 27 = 1).
Check, if can decipher your output now:
E(8) = 7*8 + 5 mod 27 = 7
D(7) = 4 * (7 - 5) mod 27 = 8
Hope that helps :)
Please note that the other answers do not take into account the the algorithm at hand is the Affine Cipher, ie there are some conditions at hand, the most important one the coprime status of k1 and m.
In your case it would be:
m = 27; // letters in your alphabet
k1 = 7; // coprime with m
k2 = 5; // no reqs here, just that a value above 27 is the same as mod 27 of that value
int Encrypt(int letter) {
return ((letter * k1) + k2) % m;
}
int Decrypt(int letter) {
return ((letter - k2) * modInverse(k1, m)) % m;
}
Tuple<int, Tuple<int, int>> extendedEuclid(int a, int b)
{
int x = 1, y = 0;
int xLast = 0, yLast = 1;
int q, r, m, n;
while (a != 0)
{
q = b / a;
r = b % a;
m = xLast - q * x;
n = yLast - q * y;
xLast = x; yLast = y;
x = m; y = n;
b = a; a = r;
}
return new Tuple<int, Tuple<int, int>>(b, new Tuple<int, int>(xLast, yLast));
}
int modInverse(int a, int m)
{
return (extendedEuclid(a, m).Item2.Item1 + m) % m;
}
ModInverse implementation taken from http://comeoncodeon.wordpress.com/2011/10/09/modular-multiplicative-inverse/.
I have created a program that will tell the modular inverse of something. I will let you use it. It is posted below.
# Cryptomath Module
def gcf(a, b):
# Return the GCD of a & b using Euclid's Algorithm
while a != 0:
a, b = b % a, a
return b
def findModInverse(a, m):
# Return the modular inverse of a % m, which is
# the number x such that a*x % m = 1
if gcf(a, m) != 1:
return None # No mode inverese if a & m aren't relatively prime
# Calculate using the Extended Euclidean Algorithm:
u1, u2, u3 = 1, 0, a
v1, v2, v3 = 0, 1, m
while v3 != 0:
q = u3 // v3 # // is the integer division operator
v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q *
v3), v1, v2, v3
return u1 % m
Note: The modular inverse is found using the extended euclidean algorithm. Here is the Wikipedia entry for it: http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm.
Note: This needs to be imported as a module to be used. Hope it helps.

why this would result in long integer overflow

I checked the document that long= int64 has range more than 900,000,000,000,000
Here is my code:
int r = 99;
long test1 = r*r*r*r*r;
at runtime it gives me 919,965,907 instead of the correct 9,509,900,499.
another test
long test2 = 99*99*99*99*99;
It refuses to compile, saying integer overflow.
But if i do this
long test3 = 10100200300;
This works fine.
The problem is that the literal "99" is being treated as an int. If you add "L" it will treat it as a long. To fix your compilation problem:
long test2 = 99L * 99L * 99L * 99L * 99L;
And to fix the "incorrect result" caused by integer overflow:
long r = 99;
long test1 = r * r * r * r * r;
The key point is that the expression to the right of the "=" is evaluated before the assignment to long r is done.
There are other literal suffixes you might be interested in:
Type Suffix Example
uint U or u 100U
long L or l 100L
ulong UL or ul 100UL
float F or f 123.45F
decimal M or m 123.45M
#m.edmonson, regarding your question about why it comes out to 919965907. What's happening, is that the value is "wrapping" around int.MaxValue. You can see this with a little test program:
int i = 99; // 99
i *= 99; // 9801
i *= 99; // 970299
i *= 99; // 96059601
i *= 99; // 919965907 should be 9509900499 but comes out to 919965907
// which is (9509900499 % int.MaxValue)
long k = 9509900499 % int.MaxValue;
What is meant by "wrapping around"? When you exceed int.MaxValue by 1, the value "goes back" to int.MinValue.
int j = int.MaxValue;
j++;
bool isNowMinValue = (j == int.MinValue); // true, the value has "wrapped around"
This is a bit simplistic; if you search for "integer overflow" you will get a better explanation. It's worth understanding how integers (and other numeric types) are represented with 32 bits:
http://en.wikipedia.org/wiki/Signed_number_representations
It's using integer multiplication :
long r = 99;
long test1 = r*r*r*r*r;
As the other have said, but:
long test2 = 99L * 99 * 99 * 99 * 99;
This will give you the correct result with less L around :-)
This happens because the first 99L is a long, so all the multiplications are done in the long "field" and all the other integers are upcasted to long before the multiplication (clearly the multiplication is always between 2 numbers and it's from left to right, so it's like (((99L * 99) * 99) * 99) * 99 and each "partial" result is a long and causes the next operand to be converted to long.)
Your second test fails because each 99 is an integer; replace it with the following and it compiles.
long test2 = 99L * 99L * 99L * 99L * 99L;
See the MSDN Long Documentation for details.
The compiler is looking at 99 as integers, even though the final result will be long.
This will work.
long test2 = 99L*99L*99L*99L*99L;

Converting a int to a BCD byte array

I want to convert an int to a byte[2] array using BCD.
The int in question will come from DateTime representing the Year and must be converted to two bytes.
Is there any pre-made function that does this or can you give me a simple way of doing this?
example:
int year = 2010
would output:
byte[2]{0x20, 0x10};
static byte[] Year2Bcd(int year) {
if (year < 0 || year > 9999) throw new ArgumentException();
int bcd = 0;
for (int digit = 0; digit < 4; ++digit) {
int nibble = year % 10;
bcd |= nibble << (digit * 4);
year /= 10;
}
return new byte[] { (byte)((bcd >> 8) & 0xff), (byte)(bcd & 0xff) };
}
Beware that you asked for a big-endian result, that's a bit unusual.
Use this method.
public static byte[] ToBcd(int value){
if(value<0 || value>99999999)
throw new ArgumentOutOfRangeException("value");
byte[] ret=new byte[4];
for(int i=0;i<4;i++){
ret[i]=(byte)(value%10);
value/=10;
ret[i]|=(byte)((value%10)<<4);
value/=10;
}
return ret;
}
This is essentially how it works.
If the value is less than 0 or greater than 99999999, the value won't fit in four bytes. More formally, if the value is less than 0 or is 10^(n*2) or greater, where n is the number of bytes, the value won't fit in n bytes.
For each byte:
Set that byte to the remainder of the value-divided-by-10 to the byte. (This will place the last digit in the low nibble [half-byte] of the current byte.)
Divide the value by 10.
Add 16 times the remainder of the value-divided-by-10 to the byte. (This will place the now-last digit in the high nibble of the current byte.)
Divide the value by 10.
(One optimization is to set every byte to 0 beforehand -- which is implicitly done by .NET when it allocates a new array -- and to stop iterating when the value reaches 0. This latter optimization is not done in the code above, for simplicity. Also, if available, some compilers or assemblers offer a divide/remainder routine that allows retrieving the quotient and remainder in one division step, an optimization which is not usually necessary though.)
Here's a terrible brute-force version. I'm sure there's a better way than this, but it ought to work anyway.
int digitOne = year / 1000;
int digitTwo = (year - digitOne * 1000) / 100;
int digitThree = (year - digitOne * 1000 - digitTwo * 100) / 10;
int digitFour = year - digitOne * 1000 - digitTwo * 100 - digitThree * 10;
byte[] bcdYear = new byte[] { digitOne << 4 | digitTwo, digitThree << 4 | digitFour };
The sad part about it is that fast binary to BCD conversions are built into the x86 microprocessor architecture, if you could get at them!
Here is a slightly cleaner version then Jeffrey's
static byte[] IntToBCD(int input)
{
if (input > 9999 || input < 0)
throw new ArgumentOutOfRangeException("input");
int thousands = input / 1000;
int hundreds = (input -= thousands * 1000) / 100;
int tens = (input -= hundreds * 100) / 10;
int ones = (input -= tens * 10);
byte[] bcd = new byte[] {
(byte)(thousands << 4 | hundreds),
(byte)(tens << 4 | ones)
};
return bcd;
}
maybe a simple parse function containing this loop
i=0;
while (id>0)
{
twodigits=id%100; //need 2 digits per byte
arr[i]=twodigits%10 + twodigits/10*16; //first digit on first 4 bits second digit shifted with 4 bits
id/=100;
i++;
}
More common solution
private IEnumerable<Byte> GetBytes(Decimal value)
{
Byte currentByte = 0;
Boolean odd = true;
while (value > 0)
{
if (odd)
currentByte = 0;
Decimal rest = value % 10;
value = (value-rest)/10;
currentByte |= (Byte)(odd ? (Byte)rest : (Byte)((Byte)rest << 4));
if(!odd)
yield return currentByte;
odd = !odd;
}
if(!odd)
yield return currentByte;
}
Same version as Peter O. but in VB.NET
Public Shared Function ToBcd(ByVal pValue As Integer) As Byte()
If pValue < 0 OrElse pValue > 99999999 Then Throw New ArgumentOutOfRangeException("value")
Dim ret As Byte() = New Byte(3) {} 'All bytes are init with 0's
For i As Integer = 0 To 3
ret(i) = CByte(pValue Mod 10)
pValue = Math.Floor(pValue / 10.0)
ret(i) = ret(i) Or CByte((pValue Mod 10) << 4)
pValue = Math.Floor(pValue / 10.0)
If pValue = 0 Then Exit For
Next
Return ret
End Function
The trick here is to be aware that simply using pValue /= 10 will round the value so if for instance the argument is "16", the first part of the byte will be correct, but the result of the division will be 2 (as 1.6 will be rounded up). Therefore I use the Math.Floor method.
I made a generic routine posted at IntToByteArray that you could use like:
var yearInBytes = ConvertBigIntToBcd(2010, 2);
static byte[] IntToBCD(int input) {
byte[] bcd = new byte[] {
(byte)(input>> 8),
(byte)(input& 0x00FF)
};
return bcd;
}

Categories

Resources