C# version of jquery.md5.js - c#

I try to convert the awesome script jquery.md5.js to C# for my own purpose.
But I can't figure it out these two methods:
function rstr2binl(input) {
var i,
output = [];
output[(input.length >> 2) - 1] = undefined;
for (i = 0; i < output.length; i += 1) {
output[i] = 0;
}
for (i = 0; i < input.length * 8; i += 8) {
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
}
return output;
}
I don't understand very well what is he doing with "output"...
function rstr_hmac_md5(key, data) {
var i,
bkey = rstr2binl(key),
ipad = [],
opad = [],
hash;
ipad[15] = opad[15] = undefined;
if (bkey.length > 16) {
bkey = binl_md5(bkey, key.length * 8);
}
for (i = 0; i < 16; i += 1) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
}
"ipad[15] = opad[15] = undefined;"
I can't do that in C#...
Thanks beforehand!
P.S.: Strange behavior, I can't say Hello, its always deleted...

I won't translate all code to C#, but explain a few points:
var output = [];
output[(input.length >> 2) - 1] = undefined;
This is one way to set the array length in javascript. Basically you say thet elements [0 ... (input.length >> 2) - 1] are undefined - which can be compared to null in C#. As you are calculating some values I would avoid nullable types and simply initialize the array to 0 - So the C# equivalent would be:
int[] output = new int[(input.Length >> 2)];
The next thing is that instead of normal division right bit shifts are used. If you compare the C# and JavaScript descriptions of the operators, you'll see they're doing the same thing. Therefore, no conversion is required but you could simply write new int[input.Length / 4].
Please note that in the current version of the script the array initialization is done like this:
var output = Array(input.length >> 2);
And as a final note: unless you are doing this for self-education, take an existing C# MD5 implementation, there should be plenty avaliable. This will help you to avoid errors and performance issues.

Related

Optimal solution for "Bitwise AND" problem in C#

Problem statement:
Given an array of non-negative integers, count the number of unordered pairs of array elements, such that their bitwise AND is a power of 2.
Example:
arr = [10, 7, 2, 8, 3]
Answer: 6 (10&7, 10&2, 10&8, 10&3, 7&2, 2&3)
Constraints:
1 <= arr.Count <= 2*10^5
0 <= arr[i] <= 2^12
Here's my brute-force solution that I've come up with:
private static Dictionary<int, bool> _dictionary = new Dictionary<int, bool>();
public static long CountPairs(List<int> arr)
{
long result = 0;
for (var i = 0; i < arr.Count - 1; ++i)
{
for (var j = i + 1; j < arr.Count; ++j)
{
if (IsPowerOfTwo(arr[i] & arr[j])) ++result;
}
}
return result;
}
public static bool IsPowerOfTwo(int number)
{
if (_dictionary.TryGetValue(number, out bool value)) return value;
var result = (number != 0) && ((number & (number - 1)) == 0);
_dictionary[number] = result;
return result;
}
For small inputs this works fine, but for big inputs this works slow.
My question is: what is the optimal (or at least more optimal) solution for the problem? Please provide a graceful solution in C#. 😊
One way to accelerate your approach is to compute the histogram of your data values before counting.
This will reduce the number of computations for long arrays because there are fewer options for value (4096) than the length of your array (200000).
Be careful when counting bins that are powers of 2 to make sure you do not overcount the number of pairs by including cases when you are comparing a number with itself.
We can adapt the bit-subset dynamic programming idea to have a solution with O(2^N * N^2 + n * N) complexity, where N is the number of bits in the range, and n is the number of elements in the list. (So if the integers were restricted to [1, 4096] or 2^12, with n at 100,000, we would have on the order of 2^12 * 12^2 + 100000*12 = 1,789,824 iterations.)
The idea is that we want to count instances for which we have overlapping bit subsets, with the twist of adding a fixed set bit. Given Ai -- for simplicity, take 6 = b110 -- if we were to find all partners that AND to zero, we'd take Ai's negation,
110 -> ~110 -> 001
Now we can build a dynamic program that takes a diminishing mask, starting with the full number and diminishing the mask towards the left
001
^^^
001
^^
001
^
Each set bit on the negation of Ai represents a zero, which can be ANDed with either 1 or 0 to the same effect. Each unset bit on the negation of Ai represents a set bit in Ai, which we'd like to pair only with zeros, except for a single set bit.
We construct this set bit by examining each possibility separately. So where to count pairs that would AND with Ai to zero, we'd do something like
001 ->
001
000
we now want to enumerate
011 ->
011
010
101 ->
101
100
fixing a single bit each time.
We can achieve this by adding a dimension to the inner iteration. When the mask does have a set bit at the end, we "fix" the relevant bit by counting only the result for the previous DP cell that would have the bit set, and not the usual union of subsets that could either have that bit set or not.
Here is some JavaScript code (sorry, I do not know C#) to demonstrate with testing at the end comparing to the brute-force solution.
var debug = 0;
function bruteForce(a){
let answer = 0;
for (let i = 0; i < a.length; i++) {
for (let j = i + 1; j < a.length; j++) {
let and = a[i] & a[j];
if ((and & (and - 1)) == 0 && and != 0){
answer++;
if (debug)
console.log(a[i], a[j], a[i].toString(2), a[j].toString(2))
}
}
}
return answer;
}
function f(A, N){
const n = A.length;
const hash = {};
const dp = new Array(1 << N);
for (let i=0; i<1<<N; i++){
dp[i] = new Array(N + 1);
for (let j=0; j<N+1; j++)
dp[i][j] = new Array(N + 1).fill(0);
}
for (let i=0; i<n; i++){
if (hash.hasOwnProperty(A[i]))
hash[A[i]] = hash[A[i]] + 1;
else
hash[A[i]] = 1;
}
for (let mask=0; mask<1<<N; mask++){
// j is an index where we fix a 1
for (let j=0; j<=N; j++){
if (mask & 1){
if (j == 0)
dp[mask][j][0] = hash[mask] || 0;
else
dp[mask][j][0] = (hash[mask] || 0) + (hash[mask ^ 1] || 0);
} else {
dp[mask][j][0] = hash[mask] || 0;
}
for (let i=1; i<=N; i++){
if (mask & (1 << i)){
if (j == i)
dp[mask][j][i] = dp[mask][j][i-1];
else
dp[mask][j][i] = dp[mask][j][i-1] + dp[mask ^ (1 << i)][j][i - 1];
} else {
dp[mask][j][i] = dp[mask][j][i-1];
}
}
}
}
let answer = 0;
for (let i=0; i<n; i++){
for (let j=0; j<N; j++)
if (A[i] & (1 << j))
answer += dp[((1 << N) - 1) ^ A[i] | (1 << j)][j][N];
}
for (let i=0; i<N + 1; i++)
if (hash[1 << i])
answer = answer - hash[1 << i];
return answer / 2;
}
var As = [
[10, 7, 2, 8, 3] // 6
];
for (let A of As){
console.log(JSON.stringify(A));
console.log(`DP, brute force: ${ f(A, 4) }, ${ bruteForce(A) }`);
console.log('');
}
var numTests = 1000;
for (let i=0; i<numTests; i++){
const N = 6;
const A = [];
const n = 10;
for (let j=0; j<n; j++){
const num = Math.floor(Math.random() * (1 << N));
A.push(num);
}
const fA = f(A, N);
const brute = bruteForce(A);
if (fA != brute){
console.log('Mismatch:');
console.log(A);
console.log(fA, brute);
console.log('');
}
}
console.log("Done testing.");
int[] numbers = new[] { 10, 7, 2, 8, 3 };
static bool IsPowerOfTwo(int n) => (n != 0) && ((n & (n - 1)) == 0);
long result = numbers.AsParallel()
.Select((a, i) => numbers
.Skip(i + 1)
.Select(b => a & b)
.Count(IsPowerOfTwo))
.Sum();
If I understand the problem correctly, this should work and should be faster.
First, for each number in the array we grab all elements in the array after it to get a collection of numbers to pair with.
Then we transform each pair number with a bitwise AND, then counting the number that satisfy our 'IsPowerOfTwo;' predicate (implementation here).
Finally we simply get the sum of all the counts - our output from this case is 6.
I think this should be more performant than your dictionary based solution - it avoids having to perform a lookup each time you wish to check power of 2.
I think also given the numerical constraints of your inputs it is fine to use int data types.

Convert an 8-bit character string to a sequence of 16-word blocks

I'm trying converse PHP and Javascript page to C# with password hashing system (password hashing with chap token). So I have example page to show steps result:
<?php
$chapid='\115';
$chapchallenge= '\274\013\242\243\236\226\151\224\070\023\243\207\252\061\016\254';
$pass = '123456';
?>
<script type="text/javascript">
<!--
alert('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>');
alert(((str2binl('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>'))));
alert((coreMD5(str2binl('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>'))));
alert(binl2hex(coreMD5(str2binl('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>'))));
//-->
</script>
/*
* Convert an 8-bit character string to a sequence of 16-word blocks, stored
* as an array, and append appropriate padding for MD4/5 calculation.
* If any of the characters are >255, the high byte is silently ignored.
*/
function str2binl(str)
{
var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks
var blks = new Array(nblk * 16)
for(var i = 0; i < nblk * 16; i++) blks[i] = 0
for(var i = 0; i < str.length; i++)
blks[i>>2] |= (str.charCodeAt(i) & 0xFF) << ((i%4) * 8)
blks[i>>2] |= 0x80 << ((i%4) * 8)
blks[nblk*16-2] = str.length * 8
return blks
}
First alert displays string "M123456¼¢£i8£ª1¬", so in my code I converted input using:
public static string AsciiOctalToString(string ascii)
{
var list = ascii.Split('\\');
StringBuilder builder = new StringBuilder();
foreach (string octalPart in list.Where(x => x.Length > 0))
{
int i = Convert.ToInt32(octalPart, 8);
builder.Append(Convert.ToChar(i));
}
return builder.ToString();
}
Next I have to convert this string to bytes (like str2binl(str)) but it is in some strange format. I don't understand how to 'Convert an 8-bit character string to a sequence of 16-word blocks'. Expected result (from alert 2) is {858927437, -1137298124, -1633443317, 949250454, -1433951469, -2136207823, 0, 0,0,0,0,0,0,0,184,0}. I translated str2binl(str) to:
public static int[] Str2Binl(string str)
{
var nblk = ((str.Length + 8) >> 6) + 1; // number of 16-word blocks
var blks = new int[nblk*16];
for (var i = 0; i < str.Length; i++)
{
blks[i >> 2] |= (str[i] & 0xFF) << (i%4*8);
blks[i >> 2] |= 0x80 << (i%4*8);
}
blks[nblk*16 - 2] = str.Length*8;
return blks;
}
but my result is different than expected.
Do you know what I'm doing wrong with this?
I added brackets for JavaScript code:
function str2binl(str)
{
var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks
var blks = new Array(nblk * 16)
for(var i = 0; i < nblk * 16; i++)
{
blks[i] = 0
}
for(var i = 0; i < str.length; i++)
{
blks[i>>2] |= (str.charCodeAt(i) & 0xFF) << ((i%4) * 8)
}
blks[i>>2] |= 0x80 << ((i%4) * 8)
blks[nblk*16-2] = str.length * 8
return blks
}
but line blks[i>>2] |= 0x80 << ((i%4) * 8) needs iterator too so how it's work in JS?
P.S. I can't use this JS library in my code, I need only hashed password (it's not a web app).
It seems the issue is that you placed two lines inside the for loop instead of only one. Does this work?
public static int[] Str2Binl(string str)
{
var nblk = ((str.Length + 8) >> 6) + 1; // number of 16-word blocks
var blks = new int[nblk*16];
int i;
for (i = 0; i < str.Length; i++)
{
blks[i >> 2] |= (str[i] & 0xFF) << (i%4*8);
}
blks[i >> 2] |= 0x80 << (i%4*8);
blks[nblk*16 - 2] = str.Length*8;
return blks;
}
Anyway, as I already commented, If you are really concerned about security, you shouldn't do your own hashing, nor even use MD5 or SHA, but one derived from PBKDF2. Unless if for some reason you need to keep your current algorithm.
On the other hand, your AsciiOctalToString gives me a different string: ¼♂¢£??i?8‼£?ª1♫¬.
BTW, you can avoid using that where with this (although you may like it less):
var list = ascii.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);

What is the most performant method for setting a subset of sequential items in a large array?

I am working with camera streams. I bring in 1,228,800 bytes per frame, so efficiency is crucial and nanoseconds per byte add up quickly.
I've come up with some example code below to describe the problem as succinctly as possible without seeming too contrived.
There are plenty of inefficiencies in this example code such as defining variables inside of loops, or dividing the brightness value instead of just using a composite value. These aren't my concern, and are just there to make the example simpler.
What I need advice on is the most performant method in C# for setting 3 sequential values at some determined location in a very large array, such as in the case below where I'm setting BGR to 255 while skipping the 4th byte.
Edit: To clarify, the concerning issue is where I'm reindexing Output for each index that is being set. It seems like there should potentially be some method for not traversing the entire array for each value if I already have the location of the previous item.
// Colors are stored as 4 bytes: BGRX where X is always 0
public byte[] Input = new byte[640 * 480 * 4];
public byte[] Output = new byte[640 * 480 * 4];
public int Threshold = 180;
public void ProcessImage() {
for (int i = 0; i < Input.Length; i += 4) {
var brightness = (Input[i] + Input[i + 1] + Input[i + 2]) / 3; // some value under 255
if (brightness > Threshold) {
// What is the most efficient way possible to do this?
Output[i] = 255 - Input[i];
Output[i + 1] = 255 - Input[i + 1];
Output[i + 2] = 255 - Input[i + 2];
}
else {
Output[i] = Input[i];
Output[i + 1] = Input[i + 1];
Output[i + 2] = Input[i + 2];
}
}
}
This (untested, and unsafe) code should be faster, if all you care about is speed:
public void ProcessImage()
{
int ilength = Input.Length;
Debug.Assert(ilength == Output.Length);
Debug.Assert(ilength%4 == 0);
unsafe
{
GCHandle pinned1 = GCHandle.Alloc(Input, GCHandleType.Pinned);
byte* input = (byte*)pinned1.AddrOfPinnedObject();
GCHandle pinned2 = GCHandle.Alloc(Input, GCHandleType.Pinned);
byte* output = (byte*)pinned2.AddrOfPinnedObject();
for (int i = 0; i < ilength; i += 4)
{
var brightness = (*(input) + *(input + 1) + *(input + 2)) / 3;
if (brightness > Threshold)
{
// What is the most efficient way possible to do this?
(*(output)) = (byte)(255 - *(input));
(*(output+1)) = (byte)(255 - *(input+1));
(*(output+2)) = (byte)(255 - *(input+2));
}
else
{
(*(output)) = *(input);
(*(output + 1)) = *(input + 1);
(*(output + 2)) = *(input + 2);
}
input += 4;
output += 4;
}
pinned1.Free();
pinned2.Free();
}
}
Note that I've incorporate the necessary assumptions at the top of the function. I'd suggest you always do this, but whether you prefer Debug.Assert or some other form of validation is up to you.
If you're happy to carry the 4th byte through, it would be quicker to copy Input to Output first with a block copy, then not to perform the else clause of the branch:
Buffer.BlockCopy(Input,0,Output,0,Input.Length);
for (int i = 0; i < Input.Length; i += 4) {
var brightness = (Input[i] + Input[i + 1] + Input[i + 2]) / 3;
if (brightness > Threshold) {
Output[i] = (byte)(255 - Input[i]);
Output[i + 1] = (byte)(255 - Input[i + 1]);
Output[i + 2] = (byte)(255 - Input[i + 2]);
}
}
In terms of the most performant way of setting a single value to multiple array indicies in c#, I think you're looking at it. There's no non-looping way to set the same value to multiple indicies. See How can I assign a value to multiple array indices at once without looping?
If it helps, there's no need for the else statement where you set the 3 indicies to 0. default(byte) is already zero, so every index in the Ouput[] array will initialize to 0.
As a side note, defining variables inside of loops vs outside of loops has no effect on the resulting IL. See Is it better to declare a variable inside or outside a loop?
EDIT: To add on to the comment above, you can use unsafe methods. See https://stackoverflow.com/a/5375552/3290789 and http://www.gutgames.com/post/Using-Unsafe-Code-for-Faster-Image-Manipulation.aspx

Int to byte array and back doesnt give the same value on big numbers

I'm trying to convert an int to an byte array and then do base64 to create a blockId for Azure Rest API. I've gotten the first bit correct, the when where I convert the int to a base64 string:
int a = 127;
int b = 4000;
C#:
byte[] blockIdBytes = BitConverter.GetBytes(a);
string blockIdBase64 = Convert.ToBase64String(blockIdBytes);
a gives "fwAAAA==" and b gives "oA8AAA=="
C++
QByteArray temp;
for(int i = 0; i < sizeof(a); i++) {
temp.append((char)(a >> (i * 8)));
}
a gives "fwAAAA==" and b gives "oA8AAA==" (same values as above, which is correct)
Now the issue is, when I try to convert the base64-string back to an int? My bytearray to int method does not work on numbers bigger than 127, why?
int result = 0;
for(int i = temp.size(); i >= 0; i--) {
result = (result << 8) + temp[i];
}
127 works but when I do 128 (for example) the result is "-128". I realize the it overflows, but why and where?
EDIT:
Tried:
QByteArray temp;
int a = 340;
for(int i = 0; i < sizeof(a); i++) {
temp.append((unsigned char)(a >> (i * 8)));
}
Which actaully gives "340" when I convert it back, "255" gives "-1" and "256" gives "256"
when you are converting back you need to treat all the values in temp[i] as unsigned char
or ignore the signed bit . In the below code snippet you end up promoting temp[i] to integer then explicitly we reset the signed bit if any to 0 making it positive
result = (result << 8) + ((int)(temp[i]) & 0xFF)
you should be able to achieve the same using
result = (result << 8) + ((unsigned char)(temp[i]))

HEX to bit[ ] array (also known as bool[ ])

I'm kindda new to c# and i was looking for some ideas on 2 thing. I have looked far and wide for answers but haven't found an answer to my exact problem.
I have a byte array (called BA) within a for loop which keeps over-writting itself and there is no way for my to be able print it as a whole array. Is there a way to export it outside the for loop (maybe with a different name) so i can use it later on in the program? i just want something like this:
byte[] BA2 = {3 187,3 203,111 32, ...etc}; //(groups of 2bytes separated by commas).
From the original
string hexValues = "03 BB,03 CB,6F 20,57 6F,72 6C,64 21";
(and also to represent this information in bits (boolean) so {00000011 10111011,00000011 11001011, ...etc})
The second thing i must do is to shift these two bytes by 4 and apply and AND gate with FFF0 (which is the same as multiplying the first byte * 1, and the second by 0xF0). Then put this in a ushort[ ] (unsigned short array) which holds the transformed bytes in binary format and then from there convert it back to HEX.
I understand that this might be unclear (my code is kind of messy), and pretty complex. but i was hoping some of you c# guru's could lend me hand.
Here's my code so far, i have put in comments the bits that don't work so the code runs. but i desperatly need to fix them.
class Program
{
static void Main(string[] args)
{
string hexValues = "03 BB,03 CB,6F 20,57 6F,72 6C,64 21";
string[] hex2byte = hexValues.Split(',');
for (int j = 0; j < 6; j++)
{
Console.WriteLine("\n2 byte String is: "+ hex2byte[j]);
string[] hex1byte = hex2byte[j].Split(' ');
for (int k = 0; k < 2; k++)
{
Console.WriteLine("byte " + hex1byte[k]);
byte[] BA = StringToByteArray((hex1byte[k]));
//bool[] AA = BitConverter.ToBoolean(BA); // I'm essentially stuck here. I need somehting which actually works.
//for (int i2 = 0; i2 < 2; i2++); // This is my attemp to perform de shift and AND.
//{
// ushort[] X = new ushort[1];
// X[0] = (ushort)((ushort)(BA[0] << 4) + (ushort)((BA[1] & 0xF0) >> 4)); // They have to be in this order: ((1stByte & 0xFF) << 4) + ((2byte & 0xF0) >> 4); first to the left then the right.
//}
Console.WriteLine("Converted " + BA[0]);
}
}
//Console.WriteLine(BA[4]); // it says: Does not exist in current context. Can it only b accesed in the for loop?
Console.ReadKey();
} // Main method finishes.
// Define StringToByteArray method.
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
}
Is this what you are looking for?
string[] hexValues = new string[] { "03BB", "03CB", "6F20", "576F", "726C", "6421" };
ushort result = 0;
for (int i = 0; i < hexValues.Length; i++)
{
Console.WriteLine("2 byte String is {0}", hexValues[i]);
result = ushort.Parse(hexValues[i], NumberStyles.AllowHexSpecifier);
Console.WriteLine("converted: {0}", result.ToString());
Console.WriteLine("converted: {0}", result.ToString("x")); // "x" format in ToString -> very useful for creating hex strings.
}
For your shifting you can use the << and >> operators, and | and & for bitwise operations.

Categories

Resources