I don't manage to deal with my problem even if I have read a lot about it on internet these last few days.
I try to communicate a variable length list from my Python3 program to my Arduino Leonardo.
Actually the length of these lists is variable but there are only three possible length :
first possibility : [0, 0, 1, 176, 1, 0, 0]
second possibility : [0, 1, 11, 255]
third possibility : [0, 2, 0]
(most of the values inside these lists are variables)
My Python3 code :
with Serial(port = port, baudrate=9600, timeout=1, writeTimeout=1) as port_serie :
if port_serie.isOpen() :
for value in Datas_To_Send : #Envoi des données
s = struct.pack('!{0}B'.format(len(Datas_To_Send)), *Datas_To_Send)
port_serie.write(s)
This code sends binary values like this one :
b'\x00\x00\x01\xb0\x01\x00\x00'
(the original list to send was : [0, 0, 1, 176, 1, 0, 0])
The problem is that I absolutely don't know how to find back my original list of values with my Arduino code...
My Arduino code (quite basic) :
void changeSettings() {
if ( Serial.available() > 0 ) {
int byte_read = Serial.read() ;
Serial.println(byte_read, DEC) ;
The output of this code is a pure conversion of each character from the ASCII to the Decimal...
Output (for the binary value I gave as example) :
98
39
92
120
48
48
92
120
48
48
92
120
48
49
92
120
98
48
92
120
48
49
92
120
48
48
92
120
48
48
39
10
Do you have any idea to find the first list back ?
Thank you
It seems you need to transmit either 7, 4 or 3 values, correct?
Are all the values under 256?
So, i would send 1 byte that is either 7, 4 or 3 followed by either 7, 4 or 3 bytes of the list's elements. If any item in your list is greater than 255 and less than 65,536 you'll need to send 2 bytes per element.
Well, I found the solution thanks to #MarkSetchel's and Olmagzar's (Discord user) tips.
Python3 code :
if Datas_To_Send :
long = len(Datas_To_Send)
Datas_To_Send.insert(0, long)
with Serial(port = '/dev/cu.usbmodem14101', baudrate=9600, timeout=1, writeTimeout=1) as port_serie :
if port_serie.isOpen() :
s = struct.pack('!{0}B'.format(len(Datas_To_Send)), *Datas_To_Send)
port_serie.write(s)
port_serie.close()
So I add list length directly at the first position of my list "Datas_To_Send".
Like that I just have to read it first on Arduino's side to know how many items I have to read.
Arduino code :
void changeSettings() {
if (Serial.available() > 0)
{
unsigned char len = Serial.read();
unsigned char Datas[len] ;
for (int i = 0; i < len - 1; i++)
{
unsigned char byte_read = Serial.read();
Datas[i] = byte_read ;
}
}
}
I'm trying to "compress" an array of 16 numbers ranging from 0 to 15 into a single number.
Since each element of the array is at most 15, I can represent it with just 4 bits, so I expect to have 4 bits * 16 = 64 bits which fits a number.
To do this "compression" I use the fallowing function:
function compressArray(array) {
return array.reduce(
(pre, curr, index) => {
return (pre | (curr * Math.pow(2, index * 4)));
},
0
);
}
But after index 8 it will keep giving me the same output without computing the correct |.
What am I missing here?
I am stumped as to how to use the PgNumeric type for decimal numbers. I noticed in the tests that 1.0 and -31.0 were inserted into a table using the following instances:
PgNumeric::Positive { weight: 0, scale: 1, digits: vec![1] }
and
PgNumeric::Negative {weight: 0, scale: 1, digits: vec![31] }
I can't seem to figure out how to insert a value with digits to the right of the decimal (like 5.4321) into a table.
Short answer: PgNumeric::Positive { weight: 0, scale: 4, digits: [5, 4321] }
More examples:
// 9.87654321::numeric
PgNumeric::Positive { weight: 0, scale: 8, digits: [9, 8765, 4321] }
// 12345.6789::numeric
PgNumeric::Positive { weight: 1, scale: 4, digits: [1, 2345, 6789] }
// 100000000.000000002::numeric
PgNumeric::Positive { weight: 2, scale: 9, digits: [1, 0, 0, 0, 0, 2000] }
// 0.3::numeric
PgNumeric::Positive { weight: -1, scale: 1, digits: [3000] }
It looks as if the algorithm is:
Group your number into chunks of 4 digits starting at the decimal point and working outward. These are the digits.
Count the number of chunks needed to represent the integral part and subtract one. This is the weight.
Count the number of digits needed to represent the fractional part. This is the scale.
Test harness
Here's the code I am playing with, extracted from the tests:
extern crate diesel;
use diesel::*;
use diesel::types::*;
use diesel::pg::data_types::PgNumeric;
use diesel::pg::PgConnection;
type PgBackend = <PgConnection as Connection>::Backend;
fn main() {
let query = "100000000.000000002::numeric";
let expected_value = PgNumeric::Negative {
digits: vec![31],
weight: 0,
scale: 1,
};
assert_eq!(expected_value, query_single_value::<Numeric, PgNumeric>(query));
}
fn query_single_value<T, U: Queryable<T, PgBackend>>(sql_str: &str) -> U
where PgBackend: HasSqlType<T>,
{
use diesel::expression::dsl::sql;
let connection = connection();
select(sql::<T>(sql_str)).first(&connection).unwrap()
}
fn connection() -> PgConnection {
let result = connection_without_transaction();
result.begin_test_transaction().unwrap();
result
}
fn connection_without_transaction() -> PgConnection {
let connection_url = "postgres://localhost/some_db";
::diesel::pg::PgConnection::establish(&connection_url).unwrap()
}
Potentially useful background information
From the Postgres docs:
The scale of a numeric is the count of decimal digits in the fractional part, to the right of the decimal point. The precision of a numeric is the total count of significant digits in the whole number, that is, the number of digits to both sides of the decimal point. So the number 23.5141 has a precision of 6 and a scale of 4.
However, the Postgres code says:
/*
* In the NumericShort format, the remaining 14 bits of the header word
* (n_short.n_header) are allocated as follows: 1 for sign (positive or
* negative), 6 for dynamic scale, and 7 for weight. In practice, most
* commonly-encountered values can be represented this way.
*
* In the NumericLong format, the remaining 14 bits of the header word
* (n_long.n_sign_dscale) represent the display scale; and the weight is
* stored separately in n_weight.
*/
void display(const char *path)
{
char msg[128];
int8_t size;
memset(msg, 0, 128);
FILE *file = fopen(path, "r");
size_t n = fread(&size, 1, 1, file);
if (n == 0 || size > 128)
return;
n = fread(msg, 1, size, file);
puts(msg);
}
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;
display(argv[1]);
return 0;
}
How could I make this buffer overflow? I mean, the buffer is 128 bytes. But doesn't the code check if size is greater than 128? If it is, then it will just return early, and if not, it will only copy less than 128 bytes from file to msg?
int8_t size; is a 8-bit signed value, thus it falls in the range [-128,127].
When this code is executed :
size_t n = fread(&size, 1, 1, file);
if (n == 0 || size > 128)
return;
If size has is most significant bit set (that is size is >= 0x80), then it is treated has a negative number, thus escaping/avoiding the check.
Let say the code reads size with a value of 0x8F (this is 143 in decimal), but as the int8_t type has a size of 8 bits and a value range of [-128,127], the most significant bit is set and indicates a signed value, which means the value is -113.
Thus size is less than 128 in (n == 0 || size > 128) simply because -113 > 128 is false.
Which means the code will read more bytes than the size of the array. It will read 143 bytes but the array size is only 128, thus triggering a stack based buffer overflow.
What's the fewest number of steps needed to draw all of the cube's vertices, without picking up the pen from the paper?
So far I have reduced it to 16 steps:
0, 0, 0
0, 0, 1
0, 1, 1
1, 1, 1
1, 1, 0
0, 1, 0
0, 0, 0
1, 0, 0
1, 0, 1
0, 0, 1
0, 1, 1
0, 1, 0
1, 1, 0
1, 0, 0
1, 0, 1
1, 1, 1
I presume it can be reduced less than 16 steps as there are only 12 vertices to be drawn
You can view a working example in three.js javascript here:
http://jsfiddle.net/kmturley/5aeucehf/show/
Well I encoded a small brute force solver for this
the best solution is with 16 vertexes
took about 11.6 sec to compute
all is in C++ (visualization by OpenGL)
First the cube representation:
//---------------------------------------------------------------------------
#define a 0.5
double pnt[]=
{
-a,-a,-a, // point 0
-a,-a,+a,
-a,+a,-a,
-a,+a,+a,
+a,-a,-a,
+a,-a,+a,
+a,+a,-a,
+a,+a,+a, // point 7
1e101,1e101,1e101, // end tag
};
#undef a
int lin[]=
{
0,1,
0,2,
0,4,
1,3,
1,5,
2,3,
2,6,
3,7,
4,5,
4,6,
5,7,
6,7,
-1,-1, // end tag
};
// int solution[]={ 0, 1, 3, 1, 5, 4, 0, 2, 3, 7, 5, 4, 6, 2, 6, 7, -1 }; // found polyline solution
//---------------------------------------------------------------------------
void draw_lin(double *pnt,int *lin)
{
glBegin(GL_LINES);
for (int i=0;lin[i]>=0;)
{
glVertex3dv(pnt+(lin[i]*3)); i++;
glVertex3dv(pnt+(lin[i]*3)); i++;
}
glEnd();
}
//---------------------------------------------------------------------------
void draw_pol(double *pnt,int *pol)
{
glBegin(GL_LINE_STRIP);
for (int i=0;pol[i]>=0;i++) glVertex3dv(pnt+(pol[i]*3));
glEnd();
}
//---------------------------------------------------------------------------
Now the solver:
//---------------------------------------------------------------------------
struct _vtx // vertex
{
List<int> i; // connected to (vertexes...)
_vtx(){}; _vtx(_vtx& a){ *this=a; }; ~_vtx(){}; _vtx* operator = (const _vtx *a) { *this=*a; return this; }; /*_vtx* operator = (const _vtx &a) { ...copy... return this; };*/
};
const int _max=16; // know solution size (do not bother to find longer solutions)
int use[_max],uses=0; // temp line usage flag
int pol[_max],pols=0; // temp solution
int sol[_max+2],sols=0; // best found solution
List<_vtx> vtx; // model vertexes + connection info
//---------------------------------------------------------------------------
void _solve(int a)
{
_vtx *v; int i,j,k,l,a0,a1,b0,b1;
// add point to actual polyline
pol[pols]=a; pols++; v=&vtx[a];
// test for solution
for (l=0,i=0;i<uses;i++) use[i]=0;
for (a0=pol[0],a1=pol[1],i=1;i<pols;i++,a0=a1,a1=pol[i])
for (j=0,k=0;k<uses;k++)
{
b0=lin[j]; j++;
b1=lin[j]; j++;
if (!use[k]) if (((a0==b0)&&(a1==b1))||((a0==b1)&&(a1==b0))) { use[k]=1; l++; }
}
if (l==uses) // better solution found
if ((pols<sols)||(sol[0]==-1))
for (sols=0;sols<pols;sols++) sol[sols]=pol[sols];
// recursion only if pol not too big
if (pols+1<sols) for (i=0;i<v->i.num;i++) _solve(v->i.dat[i]);
// back to previous state
pols--; pol[pols]=-1;
}
//---------------------------------------------------------------------------
void solve(double *pnt,int *lin)
{
int i,j,a0,a1;
// init sizes
for (i=0;i<_max;i++) { use[i]=0; pol[i]=-1; sol[i]=-1; }
for(i=0,j=0;pnt[i]<1e100;i+=3,j++); vtx.allocate(j); vtx.num=j;
for(i=0;i<vtx.num;i++) vtx[i].i.num=0;
// init connections
for(uses=0,i=0;lin[i]>=0;uses++)
{
a0=lin[i]; i++;
a1=lin[i]; i++;
vtx[a0].i.add(a1);
vtx[a1].i.add(a0);
}
// start actual solution (does not matter which vertex on cube is first)
pols=0; sols=_max+1; _solve(0);
sol[sols]=-1; if (sol[0]<0) sols=0;
}
//---------------------------------------------------------------------------
Usage:
solve(pnt,lin); // call once to compute the solution
glColor3f(0.2,0.2,0.2); draw_lin(pnt,lin); // draw gray outline
glColor3f(1.0,1.0,1.0); draw_pol(pnt,sol); // overwrite by solution to visually check correctness (Z-buffer must pass also on equal values!!!)
List
is just mine template for dynamic array
List<int> x is equivalent to int x[]
x.add(5) ... adds 5 to the end of list
x.num is the used size of list in entries
x.allocate(100) preallocate list size to 100 entries (to avoid relocations slowdowns)
solve(pnt,lin) algorithm
first prepare vertex data
each vertex vtx[i] corresponds to point i-th point in pnt table
i[] list contains the index of each vertex connected to this vertex
start with vertex 0 (on cube is irrelevant the start point
otherwise there would be for loop through every vertex as start point
_solve(a)
it adds a vertex index to actual solution pol[pols]
then test how many lines is present in actual solution
and if all lines from lin[] are drawn and solution is smaller than already found one
copy it as new solution
after test if actual solution is not too long recursively add next vertex
as one of the vertex that is connected to last vertex used
to limit the number of combinations
at the end sol[sols] hold the solution vertex index list
sols is the number of vertexes used (lines-1)
[Notes]
the code is not very clean but it works (sorry for that)
hope I did not forget to copy something