Wrong u128 multiplication in Rust? [closed] - rust

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
Before I open bug, I want to check what is going on here.
I'm porting this C-code here to Rust:
unsigned __int128 r = (unsigned __int128)a * (unsigned __int128)b;
easy enough (I thought):
let r = (a as u128) * (b as u128);
Now with this input parameters I get a different multiplication result in C and Rust:
(0x56eaa5f5f650a9e3 as u128) * (0xa0cf24341e75bda9 as u128)
The results are different in Rust and C:
Rust: 0x3698fbc09d2c5b15e8889b1b676bbddb
C: 0x3698fbc0f417010bded944fe676bbddb
^^^^^^^^^^^^^^^^
I cross-checked the result, and got the same result as the C code.
Am I missing something?
=== context information added:
It is this function from xmr-stak (https://github.com/fireice-uk/xmr-stak) thas is behaving differently:
static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi)
{
unsigned __int128 r = (unsigned __int128)a * (unsigned __int128)b;
*hi = r >> 64;
return (uint64_t)r;
}
Regardless if the C implementation is wrong, I have to recreate the exact computation in Rust, because this is needed for a hash computation.

I looks like you must have a made a typo in either language:
>>> hex(0x3698fbc09d2c5b15e8889b1b676bbddb//0x56eaa5f5f650a9e3)
'0xa0cf24341e75bda9' # what your Rust code uses
>>> hex(0x3698fbc0f417010bded944fe676bbddb//0x56eaa5f5f650a9e3)
'0xa0cf24351e75bda9' # what your online calculator uses
^
Classical case of off-by-0x100000000 error :)

Related

Modifying Individual Bytes in Rust [duplicate]

This question already has answers here:
Converting number primitives (i32, f64, etc) to byte representations
(5 answers)
Closed 2 years ago.
In C, if I want to modify the most significant byte of an integer, I can do it in two different ways:
#include <stdint.h>
#include <stdio.h>
int main() {
uint32_t i1 = 0xDDDDDDDD;
printf("i1 original: 0x%X\n", i1);
uint32_t i1msb = 0xAA000000;
uint32_t i1_mask = 0x00FFFFFF;
uint32_t i1msb_mask = 0xFF000000;
i1 = (i1 & i1_mask) | (i1msb & i1msb_mask);
printf("i1 modified: 0x%X\n", i1);
uint32_t i2 = 0xDDDDDDDD;
printf("i2 original: 0x%X\n", i2);
uint32_t *i2ptr = &i2;
char *c2ptr = (char *) i2ptr;
c2ptr += 3;
*c2ptr = 0xAA;
printf("i2 modified: 0x%X\n", i2);
}
i1 original: 0xDDDDDDDD
i1 modified: 0xAADDDDDD
i2 original: 0xDDDDDDDD
i2 modified: 0xAADDDDDD
The masking approach works in both C and Rust, but I don't have not found any way to do the direct byte manipulation approach in (safe) Rust. Although it has some endianness issues that masking does not, I think these can all be resolved at compile time to provide a safe, cross-platform interface, so why is direct byte manipulation not allowed in safe Rust? Or if it is, please correct me as I have been unable to find a function for it - I am thinking something like
fn change_byte(i: &u32, byte_num: usize, new_val: u8) -> Result<(), ErrorType> { ... }
which checks that byte_num is within range before performing the operation, and in which byte_num always goes from least significant byte to most significant.
Rust doesn't have a function to modify bytes directly. It does, however, have methods to convert integers to byte arrays, and byte arrays to integers. For example, one might write
fn set_low_byte(number:u32, byte:u8)->u32{
let mut arr = number.to_be_bytes();
arr[3] = byte;
u32::from_be_bytes(arr)
}
There are also methods for little and native endian byte order. The bitmask approach is also perfectly doable, and the pointer stuff will also work if you don't mind unsafe.
playground link

Converting NodeJS byte buffer [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm trying to figure out how to convert NodeJS code like this:
const buffer = new Buffer(24);
offset = buffer.writeUInt32BE(this.a, offset);
offset = buffer.writeUInt32BE(this.b, offset);
offset = buffer.writeUInt8(this.c, offset);
offset = buffer.writeUInt16BE(d, e); 1 : 0, offset);
buffer.writeInt8(this.f, offset);
to Go.
I figured I could use
buffer := make([]byte, 24)
buffer[0] = a
buffer[2] = b
but this is not working
is there a recommended way to do something like this with Go?
You should use binary.ByteOrder.
So in your case, using Big Endian, something like :
package main
import (
"encoding/binary"
)
func main() {
buffer := make([]byte, 24)
// Uint32
binary.BigEndian.PutUint32(buffer, 1)
binary.BigEndian.PutUint32(buffer[4:], 2)
// Uint8
buffer[8] = 3
// Uint16
binary.BigEndian.PutUint16(buffer[9:], 4)
// Uint8
buffer[13] = 5
}

Canary leak (scanf("%d", num)

I'm struggling with some buffer overflow exercises regarding stack canaries. Lets say in the main function we have a buffer bufand an integer num.
So inside the main function it will look something like this:
char buf[32] = {0};
fflush(stdout);
int num;
scanf("%d", &num)
getchar();
print("%lu", *(unsigned long *)(buf + num));
Is there any sort of way that the canary can get leaked through scanf("%d", num)? I've been doing some research online, but the closest I've gotten is that giving a negative number in scanf(.... may result in memory leak (leaking the canary). But I can't seem to grasp how this works
Any help in getting me in the right direction is greatly appreciated!!

What programing language is this? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Someone know what kind of language used below:
String^ fileName = "C:\\Test1.txt";
array<Byte>^ Array = gcnew array<Byte>(512);
try
{
FileStream^ fs = File::OpenRead(fileName);
fs->Read(Array, 0, 512);fs->Close();
}
catch (...)
{
MessageBox::Show("Disk error");
Application::Exit();
}
and another example of that language:
int RotateLeft3 (int number)
{
if ( ( number & 0x20000000 ) == 0x20000000 )
{
number <<= 3;number |= 1;
}
else
number <<= 3;
return number;
}
Its C++ in .NET. You can tell by the use of ^ as pointer instead of *
This is C++/CLI, in other words the C++ variant that runs on top of the .Net CLR.
On no account should this be confused with native C++.
It looks like managed c++ from Microsoft.

Problems with my binary search and linear search [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I've tried using both binary search, and while loops and for loops in my searches and the same problem is occurring.
When my original program comes to this function call, the linear search function (displayContent) will always assign -1 to position, and after the function call the program breaks and exits.
I have tried to rearrange my program. Like I said, I tried for loops and while loops with both binary and linear search.
I am also using a structure data type of
struct info
{
string name;
double score[5];
double avg;
};
Here is my function call
cout<<"Please enter the name of the person which you would like to search. ";
getline(cin, name);
cin.ignore();
displayContent(contestant, count, name);
Here is my function definition
void displayContent(info contest[], int quantity, string id)
{
int position=-1;
bool found=false;
for(int index=0;index<quantity && !found;index++)
{
if(contest[index].name.compare(id)==0)
{
found=true;
position=index;
}
}
if(position==-1)
{
cout<<"That person was not one of the contestants.";
}
else
{
cout<<"The scores for "<<contest[position].name<<" are \n Contestant Judge1 Judge2 Judge3 Judge4 Judge5 Average"
<<"\n______________________________________________________________________"<<endl;
cout<<right<<setw(15)<<fixed<<setprecision(1) <<contest[position].name<<setw(10)<<contest[position].score[0]<<setw(8)<<contest[position].score[1]<<setw(8)<<contest[position].score[2]<<setw(8)<<contest[position].score[3]
<<setw(8)<<contest[position].score[4]<<setw(8)<<contest[position].avg<<endl;
}
}
Have you verified that getline does what you expect? Perhaps name contains a line ending character. To rule out problems with input you can try to assign a value to name you know exists in contestant before calling displayContent.
I haven't been able to spot any problems in your search algorithm.

Resources