I am newbie here but have a problem without answer. I'm working with a TM4C1294 from Texas and in code there are countless errors. But at first, I have this code. How you can see, x3 have the read from PIN ADC0, but the error give to me in the lane is (obs. ignore asterick before # and the code is not complete because the rest of the body in the CCS is too large). Thanks for the attention!!
%declaration of pointers to PIN read
#define F_SAMPLE 2000
#define x0 *ADC3_read
#define x1 *ADC2_read
#define x2 *ADC1_read
#define x3 *ADC0_read
#define x4 *ADC4_read
%declaration of variables
int PI = 3.14159;
int teste = 0;
float y_0, ya1, yb1, y_1;
float y0_aux, ya1_aux, yb1_aux;
int alfa, i, j;
%declaration of PIN read
uint32_t ADC_read[5];
uint32_t *ADC0_read=&ADC_read[0];
uint32_t *ADC1_read=&ADC_read[1];
uint32_t *ADC2_read=&ADC_read[2];
uint32_t *ADC3_read=&ADC_read[3];
uint32_t *ADC4_read=&ADC_read[4];
%control code
for( i=0; i <= 12000; i++)
{
alfa = alfa + (2*PI/200);
if (alfa >= 2*PI)
alfa = alfa - 2*PI;
j++;
y0_aux = y0_aux + x3[i]; %error=identifier "x3" is undefined
ya1_aux = ya1_aux + x3[i]*sin(alfa);
yb1_aux = yb1_aux + x3[i]*cos(alfa);
if(j==200){
y_0 = y0_aux/200;
ya1 = ya1_aux/200;
yb1 = yb1_aux/200;
y_1 = sqrt((ya1 * ya1) + (yb1 * yb1));
y0_aux = 0;
ya1_aux = 0;
yb1_aux = 0;
j = 0;
}
}
}
Caveat: This may be incomplete as I'm not sure about your final result, but we can get the compilation errors out. I had to take a slight liberty to add a main function so I could get something compilable.
Here is a reindented version of your latest program [which has errors]:
#include <stdint.h>
#include <math.h>
// declaration of pointers to PIN read
#define F_SAMPLE 2000
#define x0 *ADC3_read
#define x1 *ADC2_read
#define x2 *ADC1_read
#define x3 *ADC0_read
#define x4 *ADC4_read
int
main(void)
{
// declaration of variables
int PI = 3.14159;
int teste = 0;
float y_0,
ya1,
yb1,
y_1;
float y0_aux,
ya1_aux,
yb1_aux;
int alfa,
i,
j;
// declaration of PIN read
uint32_t ADC_read[5];
uint32_t *ADC0_read = &ADC_read[0];
uint32_t *ADC1_read = &ADC_read[1];
uint32_t *ADC2_read = &ADC_read[2];
uint32_t *ADC3_read = &ADC_read[3];
uint32_t *ADC4_read = &ADC_read[4];
// control code
for (i = 0; i <= 12000; i++) {
alfa = alfa + (2 * PI / 200);
if (alfa >= 2 * PI)
alfa = alfa - 2 * PI;
j++;
// error = identifier "x3" is undefined
y0_aux = y0_aux + x3[i];
ya1_aux = ya1_aux + x3[i] * sin(alfa);
yb1_aux = yb1_aux + x3[i] * cos(alfa);
if (j == 200) {
y_0 = y0_aux / 200;
ya1 = ya1_aux / 200;
yb1 = yb1_aux / 200;
y_1 = sqrt((ya1 * ya1) + (yb1 * yb1));
y0_aux = 0;
ya1_aux = 0;
yb1_aux = 0;
j = 0;
}
}
}
This is the gcc error output:
fix1.c: In function ‘main’:
fix1.c:9:17: error: invalid type argument of unary ‘*’ (have ‘uint32_t {aka unsigned int}’)
#define x3 *ADC0_read
^
fix1.c:46:21: note: in expansion of macro ‘x3’
y0_aux = y0_aux + x3[i];
^~
fix1.c:9:17: error: invalid type argument of unary ‘*’ (have ‘uint32_t {aka unsigned int}’)
#define x3 *ADC0_read
^
fix1.c:47:23: note: in expansion of macro ‘x3’
ya1_aux = ya1_aux + x3[i] * sin(alfa);
^~
fix1.c:9:17: error: invalid type argument of unary ‘*’ (have ‘uint32_t {aka unsigned int}’)
#define x3 *ADC0_read
^
fix1.c:48:23: note: in expansion of macro ‘x3’
yb1_aux = yb1_aux + x3[i] * cos(alfa);
^~
Here is one way to change things [this compiles cleanly]:
#include <stdint.h>
#include <math.h>
// declaration of pointers to PIN read
#define F_SAMPLE 2000
#define x0 ADC3_read
#define x1 ADC2_read
#define x2 ADC1_read
#define x3 ADC0_read
#define x4 ADC4_read
int
main(void)
{
// declaration of variables
int PI = 3.14159;
int teste = 0;
float y_0,
ya1,
yb1,
y_1;
float y0_aux,
ya1_aux,
yb1_aux;
int alfa,
i,
j;
// declaration of PIN read
uint32_t ADC_read[5];
uint32_t *ADC0_read = &ADC_read[0];
uint32_t *ADC1_read = &ADC_read[1];
uint32_t *ADC2_read = &ADC_read[2];
uint32_t *ADC3_read = &ADC_read[3];
uint32_t *ADC4_read = &ADC_read[4];
// control code
for (i = 0; i <= 12000; i++) {
alfa = alfa + (2 * PI / 200);
if (alfa >= 2 * PI)
alfa = alfa - 2 * PI;
j++;
// error = identifier "x3" is undefined
y0_aux = y0_aux + x3[i];
ya1_aux = ya1_aux + x3[i] * sin(alfa);
yb1_aux = yb1_aux + x3[i] * cos(alfa);
if (j == 200) {
y_0 = y0_aux / 200;
ya1 = ya1_aux / 200;
yb1 = yb1_aux / 200;
y_1 = sqrt((ya1 * ya1) + (yb1 * yb1));
y0_aux = 0;
ya1_aux = 0;
yb1_aux = 0;
j = 0;
}
}
}
Here is an alternate way to code it [this also compiles cleanly]:
#include <stdint.h>
#include <math.h>
// declaration of pointers to PIN read
#define F_SAMPLE 2000
#define x0(o) ADC3_read[o]
#define x1(o) ADC2_read[o]
#define x2(o) ADC1_read[o]
#define x3(o) ADC0_read[o]
#define x4(o) ADC4_read[o]
int
main(void)
{
// declaration of variables
int PI = 3.14159;
int teste = 0;
float y_0,
ya1,
yb1,
y_1;
float y0_aux,
ya1_aux,
yb1_aux;
int alfa,
i,
j;
// declaration of PIN read
uint32_t ADC_read[5];
uint32_t *ADC0_read = &ADC_read[0];
uint32_t *ADC1_read = &ADC_read[1];
uint32_t *ADC2_read = &ADC_read[2];
uint32_t *ADC3_read = &ADC_read[3];
uint32_t *ADC4_read = &ADC_read[4];
// control code
for (i = 0; i <= 12000; i++) {
alfa = alfa + (2 * PI / 200);
if (alfa >= 2 * PI)
alfa = alfa - 2 * PI;
j++;
// error = identifier "x3" is undefined
y0_aux = y0_aux + x3(i);
ya1_aux = ya1_aux + x3(i) * sin(alfa);
yb1_aux = yb1_aux + x3(i) * cos(alfa);
if (j == 200) {
y_0 = y0_aux / 200;
ya1 = ya1_aux / 200;
yb1 = yb1_aux / 200;
y_1 = sqrt((ya1 * ya1) + (yb1 * yb1));
y0_aux = 0;
ya1_aux = 0;
yb1_aux = 0;
j = 0;
}
}
}
But, indexing off from ADC0_read doesn't make sense to me. Your for loop goes to 12000, but ADC_read has only 5 elements, so either variant above will probably segfault because you're going way past the end of the array.
More likely, you may want something like:
uint32_t ADC_read[12000];
#define x3(o) ADC_read[(o) + 0]
#define x2(o) ADC_read[(o) + 1]
...
Honestly, I don't see how the individual pointers (ADC3_read, etc.) fit in [well]
Related
how are you? I have a question about an algorithm that I've been learning. It is the relatively simple algorithm, which helps to detect the edges of the image.
In summary, the algorithm works like this: it takes a 24-bit .bmp image of arbitrary dimensions and applies the Sobel operator to detect the edges in the image.
I almost managed to get satisfactory results with the code below.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
[![#pragma pack(push, 1)
typedef struct
{
char bitmapSignatureBytes\[2\];
uint32_t sizeOfBitmapImageBytes;
uint16_t reserved1;
uint16_t reserved2;
uint32_t pixelOffset;][1]][1]
}bmpFileHeader;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct
{
uint32_t dib_header_size; // DIB Header size in bytes (40 bytes)
int32_t width; // Width of the image
int32_t height; // Height of image
uint16_t num_planes; // Number of color planes
uint16_t bits_per_pixel; // Bits per pixel
uint32_t compression; // Compression type
uint32_t image_size_bytes; // Image size in bytes
int32_t x_resolution_ppm; // Pixels per meter
int32_t y_resolution_ppm; // Pixels per meter
uint32_t num_colors; // Number of colors
uint32_t important_colors; // Important colors
}bmpInfoHeader;
#pragma pack(pop)
#pragma pack(push,1)
typedef struct
{
uint8_t blue;
uint8_t green;
uint8_t red;
}pixel;
#pragma pack(pop)
int randNum(void);
int main(void){
bmpFileHeader myBmpFileHeader;
bmpInfoHeader myBmpInfoHeader;
FILE *bmpImage = fopen("work.bmp", "rb");
FILE *newBmpImage = fopen("border_work.bmp", "wb");
if (bmpImage == NULL)
{
printf("Error occured when opening file\n");
}
fread(&myBmpFileHeader, sizeof(myBmpFileHeader), 1, bmpImage);
fread(&myBmpInfoHeader, sizeof(myBmpInfoHeader), 1, bmpImage);
if (myBmpFileHeader.bitmapSignatureBytes[0]==0x42 && myBmpFileHeader.bitmapSignatureBytes[1]==0x4D && myBmpInfoHeader.dib_header_size == 40 && myBmpInfoHeader.bits_per_pixel == 24 && myBmpInfoHeader.compression ==0 )
{
printf(" File is probably BMP\n");
}else{
printf("Error\n");
}
int width = myBmpInfoHeader.width;
//printf("Width %i\n", width );
int height = abs(myBmpInfoHeader.height);
//printf("Height: %i\n", height );
pixel(*image)[width] = calloc(height, width * sizeof(pixel));
pixel(*image_blur)[width] = calloc(height, width * sizeof(pixel));
int padding = (4 - (width * sizeof(pixel)) % 4) % 4;
for (int i = 0; i < height; ++i)
{
fread(image[i], sizeof(pixel), width, bmpImage);
fseek(bmpImage, padding, SEEK_CUR);
}
int gx[3][3];
int gy[3][3];
gx[0][0] = -1;
gx[0][1] = 0;
gx[0][2] = 1;
gx[1][0] = -2;
gx[1][1] = 0;
gx[1][2] = 2;
gx[2][0] = -1;
gx[2][1] = 0;
gx[2][2] = 1;
gy[0][0] = -1;
gy[0][1] = -2;
gy[0][2] = -1;
gy[1][0] = 0;
gy[1][1] = 0;
gy[1][2] = 0;
gy[2][0] = 1;
gy[2][1] = 2;
gy[2][2] = 1;
int gxValBlue;
int gyValBlue;
int gxValGreen;
int gyValGreen;
int gxValRed;
int gyValRed;
int squaredBlue;
int squaredGreen;
int squaredRed;
for (int lin = 0; lin < height; ++lin)
{
for (int col = 0; col < width; ++col)
{
if (lin !=0 && lin != height && col != 0 && col != width)// tem todos os vizinhos
{
gxValBlue = (image[lin-1][col-1].blue * gx[0][0] + image[lin-1][col].blue * gx[0][1] + image[lin-1][col+1].blue * gx[0][2] + image[lin][col-1].blue * gx[1][0] + image[lin][col].blue * gx[1][1] + image[lin][col+1].blue * gx[1][2] + image[lin-1][col-1].blue * gx[2][0] + image[lin+1][col].blue * gx[2][1] + image[lin+1][col+1].blue * gx[2][2]);
gyValBlue = (image[lin-1][col-1].blue * gy[0][0] + image[lin-1][col].blue * gy[0][1] + image[lin-1][col+1].blue * gy[0][2] + image[lin][col-1].blue * gy[1][0] + image[lin][col].blue * gy[1][1] + image[lin][col+1].blue * gy[1][2] + image[lin-1][col-1].blue * gy[2][0] + image[lin+1][col].blue * gy[2][1] + image[lin+1][col+1].blue * gy[2][2]);
squaredBlue = (int)sqrt(gxValBlue*gxValBlue + gyValBlue*gyValBlue);
gxValGreen = (image[lin-1][col-1].green * gx[0][0] + image[lin-1][col].green * gx[0][1] + image[lin-1][col+1].green * gx[0][2] + image[lin][col-1].green * gx[1][0] + image[lin][col].green * gx[1][1] + image[lin][col+1].green * gx[1][2] + image[lin-1][col-1].green * gx[2][0] + image[lin+1][col].green * gx[2][1] + image[lin+1][col+1].green * gx[2][2]);
gyValGreen = (image[lin-1][col-1].green * gy[0][0] + image[lin-1][col].green * gy[0][1] + image[lin-1][col+1].green * gy[0][2] + image[lin][col-1].green * gy[1][0] + image[lin][col].green * gy[1][1] + image[lin][col+1].green * gy[1][2] + image[lin-1][col-1].green * gy[2][0] + image[lin+1][col].green * gy[2][1] + image[lin+1][col+1].green * gy[2][2]);
squaredGreen = (int)sqrt(gxValGreen*gxValGreen + gyValGreen*gyValGreen);
gxValRed = (image[lin-1][col-1].red * gx[0][0] + image[lin-1][col].red * gx[0][1] + image[lin-1][col+1].red * gx[0][2] + image[lin][col-1].red * gx[1][0] + image[lin][col].red * gx[1][1] + image[lin][col+1].red * gx[1][2] + image[lin-1][col-1].red * gx[2][0] + image[lin+1][col].red * gx[2][1] + image[lin+1][col+1].red * gx[2][2]);
gyValRed = (image[lin-1][col-1].red * gy[0][0] + image[lin-1][col].red * gy[0][1] + image[lin-1][col+1].red * gy[0][2] + image[lin][col-1].red * gy[1][0] + image[lin][col].red * gy[1][1] + image[lin][col+1].red * gy[1][2] + image[lin-1][col-1].red * gy[2][0] + image[lin+1][col].red * gy[2][1] + image[lin+1][col+1].red * gy[2][2]);
squaredRed = (int)sqrt(gxValRed*gxValRed + gyValRed*gyValRed);
if (squaredBlue > 255)
{
image_blur[lin][col].blue = 255;
}else{
image_blur[lin][col].blue = squaredBlue;
}
if (squaredGreen > 255)
{
image_blur[lin][col].green = 255;
}else{
image_blur[lin][col].green = squaredGreen;
}
if (squaredRed > 255)
{
image_blur[lin][col].red = 255;
}else{
image_blur[lin][col].red = squaredRed;
}
}else { // bottom
image_blur[lin][col].blue = 0;
image_blur[lin][col].green = 0;
image_blur[lin][col].red = 0;
}
}
}
fwrite(&myBmpFileHeader, sizeof(myBmpFileHeader),1, newBmpImage);
fwrite(&myBmpInfoHeader, sizeof(myBmpInfoHeader), 1, newBmpImage);
for (int i = 0; i < width; ++i)
{
for (int k = 0; k < padding; ++k)
{
fputc(0x00, newBmpImage);
}
fwrite(image_blur[i], sizeof(pixel), width, newBmpImage);
}
fclose(newBmpImage);
fclose(bmpImage);
free(image);
free(image_blur);
return 0;
}
I am also sending an example of the original image and modified image.
As you can see, the modified image is cropped.
The two images have the same dimensions, but the modified image appears cropped.
My assumptions that it may be happening:
misuse of calloc () that is not providing enough memory to store the modified image
problem with padding
I have had this problem for a long time and I would like to ask the community for help to resolve this issue and raise my level of proficiency in C.
The reason for the cropped output is what user3386109 said: when writing the output BMP, the outer loop
for (int i = 0; i < width; ++i)
should iterate up to height, not width. BMPs are stored starting from the bottom row, this is why a portion of the top of the image went missing.
A minor comment about the filtering: there is a check that appears to intend to exclude a one-pixel margin for boundary handling,
if (lin !=0 && lin != height && col != 0 && col != width)
Beware there is an off-by-one error on the right and bottom edges. Since lin iterates for lin < height, the bottom row is lin == height - 1, not height. Similarly col == width - 1 is the rightmost column.
I can't find and resolve the error in this code.
I want Parray and Tarray to be filled with an iteration of the equation in the loop. I tried both for and while loop, but it seems that only the first member of the array is given proper value, and that value is lost by the beginning of a new cycle.
#include <stdio.h>
#include <stdlib.h>
int main() {
int i;
int j;
float dt,P_init,t_init,t_end;
dt = 0.03125;
P_init = 30;
t_init = 0;
t_end = 30;
int n_steps = 0;
n_steps = t_end/(float)dt;
int Parray[n_steps+1];
int Tarray[n_steps+1];
for (i=0; i<n_steps+1; i++)
{
Parray[i]=0;
Tarray[i]=0;
}
Parray[0] = P_init;
Tarray[0] = t_init;
int x;
float P,t,dpdt;
x = 1;
while (x < n_steps+1)
{
float s,d;
P = Parray[x-1];
t = Tarray[x-1];
dpdt = 0.7 * P * (1-(P/750)) - 20;
s = P + (dt * dpdt);
Parray[x] = s;
d = t + dt;
Tarray[x] = d;
x++;
printf("%f %f ",s,d);
}
return(0);
}
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, j, x;
float dt, P_init, t_init, t_end, P, t, dpdt;
dt = 0.03125;
P_init = 30;
t_init = 0;
t_end = 30;
int n_steps = 0;
n_steps = t_end / (float)dt;
// using float arrays
float Parray[n_steps+1];
float Tarray[n_steps+1];
for (i = 0; i < n_steps+1; i++)
Parray[i] = 0;
for (j = 0; j < n_steps+1; j++)
Tarray[j] = 0;
Parray[0] = P_init;
Tarray[0] = t_init;
for (x = 1; x < n_steps + 1; x++) {
float s , d;
P = Parray[x-1];
t = Tarray[x-1];
dpdt = 0.7 * P * (1 - (P / 750)) - 20;
s = P + (dt * dpdt);
Parray[x] = s;
d = t + dt;
Tarray[x] = d;
printf("%f %f\n", s, d);
}
return(0);
}
I changed the int arrarys to float arrays.
What do you actually calculate here?
This line
dpdt = 0.7 * P * (1-(P/750)) - 20;
It seems to have a float value, therefore the array must be float type, and ALL inputs you put in the array must be in FLOAT type.
Change this:
int Parray[n_steps+1];
int Tarray[n_steps+1];
to
float Parray[n_steps+1];
float Tarray[n_steps+1];
and
P_init = 30;
t_init = 0;
t_end = 30;
All of them should be 30.0, 0.0, 30.0
Don't forget this too:
Parray[i]=0;
Tarray[i]=0;
Change it to 0.0
In short, C is bad at differentiate between types, so if you declare a float array, all inputs must be x.0, not only x where x is an integer.
I added cairo.h to run a image processing code. getting this error
ccmKP8Gv.o:flow.c:(.text+0x621): undefined reference to
`cairo_format_stride_for_width'
I think it is a linker-error, but I am not quite sure how to solve it.
Can anyone help?
Code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <cairo.h>
#ifndef M_PI
#define M_PI 3.1415927
#endif
#define GR(X,Y) (d[(*s)*(Y)+bpp*(X)+((2)%bpp)])
#define GG(X,Y) (d[(*s)*(Y)+bpp*(X)+((1)%bpp)])
#define GB(X,Y) (d[(*s)*(Y)+bpp*(X)+((0)%bpp)])
#define SR(X,Y) (ht[4*tw*((Y)%th)+4*((X)%tw)+2])
#define SG(X,Y) (ht[4*tw*((Y)%th)+4*((X)%tw)+1])
#define SB(X,Y) (ht[4*tw*((Y)%th)+4*((X)%tw)+0])
#define RAD(A) (M_PI*((double)(A))/180.0)
uint8_t *houghtransform(uint8_t *d, int *w, int *h, int *s, int bpp)
{
int rho, theta, y, x, W = *w, H = *h;
int th = sqrt(W*W + H*H)/2.0;
int tw = 360;
uint8_t *ht = ( uint8_t*)malloc(th*tw*4);
memset(ht, 0, 4*th*tw); // black bg
for(rho = 0; rho < th; rho++)
{
for(theta = 0; theta < tw/*720*/; theta++)
{
double C = cos(RAD(theta));
double S = sin(RAD(theta));
uint32_t totalred = 0;
uint32_t totalgreen = 0;
uint32_t totalblue = 0;
uint32_t totalpix = 0;
if ( theta < 45 || (theta > 135 && theta < 225) || theta > 315) {
for(y = 0; y < H; y++) {
double dx = W/2.0 + (rho - (H/2.0-y)*S)/C;
if ( dx < 0 || dx >= W ) continue;
x = floor(dx+.5);
if (x == W) continue;
totalpix++;
totalred += GR(x, y);
totalgreen += GG(x, y);
totalblue += GB(x, y);
}
} else {
for(x = 0; x < W; x++) {
double dy = H/2.0 - (rho - (x - W/2.0)*C)/S;
if ( dy < 0 || dy >= H ) continue;
y = floor(dy+.5);
if (y == H) continue;
totalpix++;
totalred += GR(x, y);
totalgreen += GG(x, y);
totalblue += GB(x, y);
}
}
if ( totalpix > 0 ) {
double dp = totalpix;
SR(theta, rho) = (int)(totalred/dp) &0xff;
SG(theta, rho) = (int)(totalgreen/dp) &0xff;
SB(theta, rho) = (int)(totalblue/dp) &0xff;
}
}
}
*h = th; // sqrt(W*W+H*H)/2
*w = tw; // 360
*s = 4*tw;
return ht;
}
void image_process(char *rgb)
{
cairo_surface_t *inputimg = NULL;
cairo_surface_t *houghimg = NULL;
uint8_t *houghdata = NULL, *inputdata = NULL;
int w, h, s, bpp;
inputimg = cairo_image_surface_create_for_data((unsigned char*)rgb, CAIRO_FORMAT_RGB24, 320, 240, cairo_format_stride_for_width ( CAIRO_FORMAT_RGB24, 320));
w = cairo_image_surface_get_width(inputimg);
h = cairo_image_surface_get_height(inputimg);
s = cairo_image_surface_get_stride(inputimg);
bpp = cairo_image_surface_get_format(inputimg);
switch(bpp)
{
case CAIRO_FORMAT_ARGB32: bpp = 4; break;
case CAIRO_FORMAT_RGB24: bpp = 3; break;
case CAIRO_FORMAT_A8: bpp = 1; break;
default:
fprintf(stderr, "unsupported\n");
goto destroy;
}
inputdata = cairo_image_surface_get_data(inputimg);
houghdata = houghtransform(inputdata, &w, &h, &s, bpp);
printf("w=%d, h=%d\n", w, h);
houghimg = cairo_image_surface_create_for_data(houghdata,
CAIRO_FORMAT_RGB24,
w, h, s);
cairo_surface_write_to_png(houghimg, "hello.png");
destroy:
if (inputimg != NULL) cairo_surface_destroy(inputimg);
if (houghimg != NULL) cairo_surface_destroy(houghimg);
}
Make sure to compile with the -lcairo flag.
If you're using the command line on linux do it like so:
gcc -o main main.c -Wall -Wextra -lcairo
Or if you're using an IDE just add -lcairo to the linker options.
I've implemented sha2 256 based on the rfc spec found at: https://www.rfc-editor.org/rfc/rfc4634.
My implementation:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
uint32_t K[] = {
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,
0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,
0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,
0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,
0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,
0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,
0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,
0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,
0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2,
};
uint32_t CH(uint32_t x, uint32_t y, uint32_t z) {
uint32_t answ = (x & y) ^ (~x & z);
return answ;
}
uint32_t MAJ(uint32_t x, uint32_t y, uint32_t z) {
uint32_t answ = (x & y) ^ (x & z) ^ (y & z);
return answ;
}
uint32_t ROTL(uint32_t x, short n) {
return (x << n) | (x>>(32 - n));
}
uint32_t ROTR(uint32_t x, short n) {
return (x >> n) | (x<<(32 - n));
}
uint32_t BIGS0(uint32_t x) {
return ROTR(x,2) ^ ROTR(x,13) ^ ROTR(x,22);
}
uint32_t BIGS1(uint32_t x) {
return ROTR(x,6) ^ ROTR(x,11) ^ ROTR(x,25);
}
uint32_t SSIG0(uint32_t x) {
return ROTR(x,7) ^ ROTR(x,18) ^ (x >> 3);
}
uint32_t SSIG1(uint32_t x) {
return ROTR(x,17) ^ ROTR(x,19) ^ (x >> 10);
}
uint32_t toInt(uint8_t *t) {
return (t[3] << 24) | (t[2] << 16) | (t[1] << 8) | t[0];
}
void process(uint32_t *block) {
uint32_t H[] = {
0x6a09e667,
0xbb67ae85,
0x3c6ef372,
0xa54ff53a,
0x510e527f,
0x9b05688c,
0x1f83d9ab,
0x5be0cd19
};
uint32_t *W = (uint32_t *) malloc (sizeof(uint32_t*) * 64);
for (int t = 0; t < 16; t++) {
W[t] = block[t];
}
for (int t = 16; t < 64; t++) {
W[t] = SSIG1(W[t-2]) + W[t-7] + SSIG0(t-15) + W[t-16];
}
uint32_t a = H[0];
uint32_t b = H[1];
uint32_t c = H[2];
uint32_t d = H[3];
uint32_t e = H[4];
uint32_t f = H[5];
uint32_t g = H[6];
uint32_t h = H[7];
uint32_t T1 = 0;
uint32_t T2 = 0;
for(int t =0; t < 64 ; t++) {
T1 = h + BIGS1(e) + CH(e,f,g) + K[t] + W[t];
T2 = BIGS0(a) + MAJ(a,b,c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
}
H[0] = a + H[0];
H[1] = b + H[1];
H[2] = c + H[2];
H[3] = d + H[3];
H[4] = e + H[4];
H[5] = f + H[5];
H[6] = g + H[6];
H[7] = h + H[7];
for (int j = 0; j < 8; j++ ) {
printf("%08x", H[j] );
}
free(W);
}
int main(void)
{
uint32_t block[] = {
0x61626380,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000018,
};//abc in 512 bit padded block
process(block);
return 0;
}
For now I'm only doing one 512 message block and my testing message is 'abc'. Doing all the preprocessing as required results in a padded message block as follows:
0x61626380 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000018
After feeding it through my implementation I get the hash as: 4b9cc43100a30340dbc8f2328e2c80a91fdbd7b8cd20962d1b64e31283c4b99d
Where as the correct hash is:
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
Tracing my output and comparing it to the example provided at http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf page 34. My implementation seems to go wrong at iteration 16 (thus t=16) when the variable e needs to be calculated.
Any help would be appreciated.
This line:
W[t] = SSIG1(W[t-2]) + W[t-7] + SSIG0(t-15) + W[t-16];
Should be
W[t] = SSIG1(W[t-2]) + W[t-7] + SSIG0(W[t-15]) + W[t-16];
The problem kicks in on iteration 16 because that's when you first refer to a value buffered using that assignment (earlier values were just copies of the initial block).
http://en.wikipedia.org/wiki/Multiply-with-carry#Complementary-multiply-with-carry_RNGs
has some code in C
I'm trying to compile it, but when I do I get this error
c:\program files (x86)\codeblocks\mingw\bin..\lib\gcc\mingw32\4.4.1......\libmingw32.a(main.o):main.c|| undefined reference to `WinMain#16'|
Here's the code
I hope to figure out how to implement it and use it instead of booster's mersenne twister.
As someone pointed out, I was missing my main function, but now with it, I'm still having an issue getting it to run.
#include <stdint.h>
#define PHI 0x9e3779b9
static uint32_t Q[4096], c = 362436;
int main
{
init_rand(6);
int c = rand_cmwc();
};
void init_rand(uint32_t x)
{
int i;
Q[0] = x;
Q[1] = x + PHI;
Q[2] = x + PHI + PHI;
for (i = 3; i < 4096; i++)
Q[i] = Q[i - 3] ^ Q[i - 2] ^ PHI ^ i;
}
uint32_t rand_cmwc(void)
{
uint64_t t, a = 18782LL;
static uint32_t i = 4095;
uint32_t x, r = 0xfffffffe;
i = (i + 1) & 4095;
t = a * Q[i] + c;
c = (t >> 32);
x = t + c;
if (x < c) {
x++;
c++;
}
return (Q[i] = r - x);
}
Okay, I figured it out.
I was missing my main function.
I then implemented the code as a class, in hopes to make it thread safe (allowing for multiple seeds)
#include <iostream>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define PHI 0x9e3779b9
using namespace std;
static uint32_t Q[4096], c = 362436;
class cmwc
{
public:
void init_rand(uint32_t x)
{
int i;
Q[0] = x;
Q[1] = x + PHI;
Q[2] = x + PHI + PHI;
for (i = 3; i < 4096; i++)
Q[i] = Q[i - 3] ^ Q[i - 2] ^ PHI ^ i;
}
uint32_t rand_cmwc(void)
{
uint64_t t, a = 18782LL;
static uint32_t i = 4095;
uint32_t x, r = 0xfffffffe;
i = (i + 1) & 4095;
t = a * Q[i] + c;
c = (t >> 32);
x = t + c;
if (x < c) {
x++;
c++;
}
return (Q[i] = r - x);
}
uint32_t random_num;
};
int main()
{
cmwc rng1;
rng1.init_rand(time(NULL));
rng1.random_num = 1 + rng1.rand_cmwc()%6;
//int r = rng1.rand_cmwc();
cout << "die: " << rng1.random_num << endl;
return 0;
}