• Welcome to the Internet Infidels Discussion Board.

The Programming Thread

A basic Gnuplot class. Titles and axis labels can be added. An adventurous person looking for a project could expand it into a C++ graphics package.

Gnuplot has to be installed but does not have to be running.

With extents >0 the plot is to the extents of the data, < 1 and plots are to the specified limits, a zoom function.

I found it easier to use C++ strings and use the .c_str() attribute when needed for C functions.

Code:
class GNUPLOT{
    public:
    int n = 1,extents = 1;
    string path = "",plot_file =" ",data_file = "";
    double xlo = 0,xhi = 1,ylo = -1, yhi = 1;
    double *x, *y;
    int plot(void);
};

int GNUPLOT::plot(void){
    int i;
    string fname = path+data_file;
    FILE *p = fopen(fname.c_str(),"w");
    if(!p){cout<<"siog file"<<endl;return 1;}
    for(i=0;i<n;i++)fprintf(p,"%20.15f  \t%20.15f\n",x[i],y[i]);
    fclose(p);

    fname = path+plot_file;
    p = fopen(fname.c_str(),"w");
    if(!p){cout<<"plot file"<<endl;return 1;}
    fprintf(p,"set term windows background rgb 'white'\n");
    fprintf(p,"reset\n");
    if(extents){
        fprintf(p,"set xrange[*:*]\n");
        fprintf(p,"set yrange[*:*]\n");
        }
    else{
        fprintf(p,"set xrange[%f:%f]\n",xlo,xhi);
        fprintf(p,"set yrange[%f:%f]\n",ylo,yhi);
        }
    fname = path + data_file;
    fprintf(p,"set grid lt 1 lw 1 lc rgb 'black'  dashtype solid\n");
    fprintf(p,"plot '%s' using 1:2 with lines ls 4 lt  -1 lw 3\n",fname.c_str());
    fprintf(p,"show grid\n");
    fclose(p);

    fname = path+plot_file;
    system(fname.c_str());
    return 0;
}

void plot_test(void){
    GNUPLOT gp;
    int i, n = 100;
    double t[n],y[n],dt = 1./(n-1);
    for(i=0;i<n;i++){
        t[i] = i*dt;
        y[i] = sin(2*_PI*1*t[i]);
    }
    gp.n = n; gp.extents = 1;
    gp.path = "c:\\gnuplot\\data\\";
    gp.plot_file = "sig.plt";
    gp.data_file = "sig.dat";
    gp.xlo = 0;gp.xhi = .4;gp.ylo = 0;gp.yhi = 1;
    gp.x = t; gp.y = y;
    gp.plot();
}
 
Basic data plotting in Gnuplot, histograms and cumulative distributions. Histograms on real data can be ragged looking. As an integration the cumulative distribution acts to smooth the data into a more recognizable plot.

The Gnuplot script is from Gnuplot documentation.

Compiled with gcc C17 ISO C++

Exponential mean > 1.

Code:
double minf(int n,double *x){
    double xmin = x[0];
    for(int i =0;i<n;i++)if(x[i] < xmin)xmin = x[i];
    return xmin;
}

double maxf(int n,double *x){
    double xmax = x[0];
    for(int i =0;i<n;i++)if(x[i] > xmax)xmax = x[i];
    return xmax;
}


class GNUPLOTHIST{
    public:
    int n,bin_width,box_width,extents = 1;
    string path,file_name;
    double *y,xlo = 0,xhi = 1;
    int plot(void);
};

int GNUPLOTHIST::plot(void){
    int i ;
    string data_file = path + file_name + ".dat";
    string plot_file  = path + file_name + ".plt";
    double *cd = new double[n];
    sort(&y[0],&y[n]);
    for(i=0;i<n;i++)cd[i] = 100*(i+1.)/n;

    FILE *p = fopen(data_file.c_str(),"w");
    if(!p){cout<<"data file error"<<endl;return 1;}
    for(i=0;i<n;i++)fprintf(p,"%10.5f \t%20.15f\n",cd[i],y[i]);
    fclose(p);

    p = fopen(plot_file.c_str(),"w");
    if(!p){cout<<"plot file"<<endl;return 1;}
    //fprintf(p,"unset multiplot\n");
    fprintf(p,"set term windows background rgb 'white'\n");// title "SIGNALS" fontscale 1\n");ntf(p,"clear\n");
    fprintf(p,"clear\n");
    fprintf(p,"reset\n");
    fprintf(p,"set key off\n");
    fprintf(p,"set multiplot layout 2,1 columnsfirst\n");

    if(extents) fprintf(p,"set xrange[%f:%f]\n",y[0],y[n-1]);
        else fprintf(p,"set xrange[%f:%f]\n",xlo,xhi);


    fprintf(p,"set border 3\n");
    fprintf(p,"set grid lt 1 lw 1 lc rgb 'black'  dashtype solid\n");
    fprintf(p,"set boxwidth  %d absolute\n",box_width);
    fprintf(p,"set style fill solid 1.0 noborder\n");
    fprintf(p,"bin_width = %d\n",bin_width);
    fprintf(p,"bin_number(x) = floor(x/bin_width)\n");
    fprintf(p,"rounded(x) = bin_width * ( bin_number(x) + 0.5 )\n");
    fprintf(p,"plot '%s' using (rounded($2)):(2) smooth frequency with boxes\n",data_file.c_str());
    fprintf(p,"show grid\n");

    fprintf(p,"set grid lt 1 lw 1 lc rgb 'black'  dashtype solid\n");
    fprintf(p,"set zeroaxis\n");
    fprintf(p,"set yrange[0:100]\n");
    fprintf(p," plot '%s' using 2:1 with lines ls 4 lt  -1 lw 3\n",data_file.c_str());
    fprintf(p,"show grid\n");
    fprintf(p,"unset multiplot\n");
    fclose(p);
    if(system(plot_file.c_str()) !=0) cout<<"system() error"<<endl;
    delete []cd;
    return 0;

}

struct hist_params{
     int n,bin_width,box_width,extents = 1;
    string path,file_name;
    double *x,*y,xlo = 0,xhi = 1;
};

int hist_plot(struct hist_params p){
    int i ;
    string data_file = p.path + p.file_name + ".dat";
    string plot_file  = p.path + p.file_name + ".plt";
    double *cd = new double[p.n];
    sort(&p.y[0],&p.y[p.n]);
    for(i=0;i<p.n;i++)cd[i] = 100*(i+1.)/p.n;

    FILE *fp = fopen(data_file.c_str(),"w");
    if(!fp){cout<<"data file error"<<endl;return 1;}
    for(i=0;i<p.n;i++)fprintf(fp,"%10.5f \t%20.15f\n",cd[i],p.y[i]);
    fclose(fp);

    fp = fopen(plot_file.c_str(),"w");
    if(!fp){cout<<"plot file"<<endl;return 1;}
    fprintf(fp,"set term windows background rgb 'white'\n");// title "SIGNALS" fontscale 1\n");ntf(p,"clear\n");
    fprintf(fp,"clear\n");
    fprintf(fp,"reset\n");
    fprintf(fp,"set key off\n");
    fprintf(fp,"set multiplot layout 2,1 columnsfirst\n");

    if(p.extents) fprintf(fp,"set xrange[%f:%f]\n",p.y[0],p.y[p.n-1]);
        else fprintf(fp,"set xrange[%f:%f]\n",p.xlo,p.xhi);


    fprintf(fp,"set border 3\n");
    fprintf(fp,"set grid lt 1 lw 1 lc rgb 'black'  dashtype solid\n");
    fprintf(fp,"set boxwidth  %d absolute\n",p.box_width);
    fprintf(fp,"set style fill solid 1.0 noborder\n");
    fprintf(fp,"bin_width = %d\n",p.bin_width);
    fprintf(fp,"bin_number(x) = floor(x/bin_width)\n");
    fprintf(fp,"rounded(x) = bin_width * ( bin_number(x) + 0.5 )\n");
    fprintf(fp,"plot '%s' using (rounded($2)):(2) smooth frequency with boxes\n",data_file.c_str());
    fprintf(fp,"show grid\n");

    fprintf(fp,"set grid lt 1 lw 1 lc rgb 'black'  dashtype solid\n");
    fprintf(fp,"set zeroaxis\n");
    fprintf(fp,"set yrange[0:100]\n");
    fprintf(fp," plot '%s' using 2:1 with lines ls 4 lt  -1 lw 3\n",data_file.c_str());
    fprintf(fp,"show grid\n");
    fprintf(fp,"unset multiplot\n");
    fclose(fp);
    if(system(plot_file.c_str()) !=0) cout<<"system() error"<<endl;
    delete []cd;
    return 0;
}



#include <random>
mt19937 rand_gen(time(NULL));


void hist_test(void){
    GNUPLOTHIST gp;
    struct hist_params p;
    int i, n = 10000;
    double mean = 0,sdev = 20;
    normal_distribution<double> dist(mean,sdev);
    //exponential_distribution<double> dist(1/mean);
    double y[n];
    for(i=0;i<n;i++)y[i] = dist(rand_gen);


    gp.n = n;
    gp.bin_width = 4;
    gp.box_width = 3;
    gp.y = y;
    gp.extents = 1;
    gp.xlo = minf(n,y);
    gp.xhi = maxf(n,y);
    gp.path = "c:\\gnuplot\\data\\";
    gp.file_name = "hist_test";

    p.n = n;
    p.bin_width = 4;
    p.box_width = 3;
    p.y = y;
    p.extents =1;
    p.xlo = 0;//minf(n,y);
    p.xhi = maxf(n,y);
    p.path = "c:\\gnuplot\\data\\";
    p.file_name = "hist_test";

    hist_plot(p);
    //gp.plot();

}
 
Last edited:
You can change bin_width and boxsize and see what it does

Exponential and Normal distribution.

1740875019303.png

1740876943341.png
 
Last edited:


About issues in JavaScript:

You can try this in Chrome and go to "Inspect" then "Console".

JavaScript:
[] + {}; // the string '[object Object]'

{} + []; // 0

{} + {}; // video says '[object Object][object Object]' but I get NaN

[] + []; // empty string

0 == []; // true

0 == "0"; // true

"0" == []; // false

2 + "2"; // '22'

2 - "2"; // 0
 


About issues in JavaScript:

You can try this in Chrome and go to "Inspect" then "Console".

JavaScript:
[] + {}; // the string '[object Object]'

{} + []; // 0

{} + {}; // video says '[object Object][object Object]' but I get NaN

[] + []; // empty string

0 == []; // true

0 == "0"; // true

"0" == []; // false

2 + "2"; // '22'

2 - "2"; // 0

Yes, it is an abomination.
 
My friend is learning python for TAFE and he told me about Thonny. It's a good IDE especially for beginners.
Here is some borrowed code I've been working on:
Python:
def fact(n):
    if n == 0:
        return 1
    else:
        return fact(n-1) * n
 
while True:
    n = int(input("Enter a natural number "))
    print (fact(n))
I can enter numbers up to around 985 - which gives the answer:

447164334462268652975255451236908403130625169421847207347930207179882137925356596830661335126582984811361344591503748102099332365118793824742910933816289257377234179780068300662699370564156675006795642496403273279205372687883966940981737891393816736049254956385702748093222920840287189302031000487091274310831363956246756881518476744443012496987893182676941139528320177292379749628765230557821264027223262586364490213597854215623968809510931891664603812159761779482877927248929355478208045732403683721889485827075268560834974486544829235266196102803632524434040137986305700077696231465933563139319339070704840202057695849216180915801503187582938413103818872255288070600754451455742656998690560562690037230281061276246643984848652108711065866555159401413587661304717836585599818845638465788635972252605194366656320902192382502376338891692627065545617079846578950985719068528736535884026409082217033256791635413341560225019935756241171049623330728724259722874287107530034512168124726110677505476881531519089451426551163966390133963913482586017900598287697819910406536815668313543799076806487596462967511152047466207953811379012602178063102972605925914596822321131693111321315266210511539459216698547963258815102042213094040041275663824029817377420254900418872776191285636545761210038359604069906727316042062613813535512635534468580620174882746741416157853373670502937167825925833922002769726562788954651391412159751411337875639245162471153571765701145240219163132812196343947707827089628135620301200554982941551872500693935045422376090798752481818786809037804194900524161563708180297114912370290860368682557726027001154132210078281656790448130731034156442377088762452053628558593484522408015316960170608107255572539842433001997578377820330648347017261764535297906032147047554784913734619915490585506495724158331835222700439508059218926052422974264313593563551170383208614375924577035411130893973042810557679570946821658194919474980648289748479798363592959130393500858722625163377025826115275488788832898287097493030935796440350260031438843457029709429153321503641755510871780512977957568493495980028553601605271395850974515621752911439479666302324909556994113771701963622740608537517452808049704606798423040846582069165293336669960297887078667198800211038202387976729072090281410560000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

If I enter 990 it says "RecursionError: maximum recursion depth exceeded in comparison"

It's good it can handle big integers without having to manually use a library.
 
Last edited:
Having nothing better to do, a password generator.

The code randomly picks 1 of 4 categories and then randomly selects a charter from the category. Upper case, lower case, numeric, non alpha numeric.

Using categories instead of randomly selecting from the entire set helps getting a mix of character types. An alternate would be to randomly shuffle the entire printable ASCII table.

Platforms may require a mix of numeric, upper case, and lower case. That may not always happen. Code can be added to check if a password meets certain requirements and make changes,

Custom categories can be created,

Alp0ha nuerc plus non alpha numeric.

, / # + l 2 . G M 5 I t 7 8 1 t

Alpha numeric only.

e 0 h 3 5 J i R X c u j x 4 9 I

Code:
# password generator

# documentation says importng random initializes the generator to system time.
import random
N = 16

def pwd_gen(n):
    # random password
    #uses decimal ascii values
    s = []
    for i in range(n):
        j = random.randint(1,4)  # select category
        match j:
            case 1:  # upper case
                lo = 65 
                hi = 90
            case 2:  # lower case
                lo = 97
                hi = 122
            case 3:  # numeric
                lo = 48
                hi = 57
            case 4:  #none alp0ha numeric
                lo = 33
                hi = 47                 
                          
        rand_ascii = random.randint(lo, hi)  #select character
        s.append(chr(rand_ascii))
        
    return s    

x = pwd_gen(N)
for i in range(N):
    print(x[i],end=" ")
 
Having nothing better to do, a password generator.

The code randomly picks 1 of 4 categories and then randomly selects a charter from the category. Upper case, lower case, numeric, non alpha numeric.

Using categories instead of randomly selecting from the entire set helps getting a mix of character types. An alternate would be to randomly shuffle the entire printable ASCII table.

Platforms may require a mix of numeric, upper case, and lower case. That may not always happen. Code can be added to check if a password meets certain requirements and make changes,

Custom categories can be created,

Alp0ha nuerc plus non alpha numeric.

, / # + l 2 . G M 5 I t 7 8 1 t

Alpha numeric only.

e 0 h 3 5 J i R X c u j x 4 9 I

Code:
# password generator

# documentation says importng random initializes the generator to system time.
import random
N = 16

def pwd_gen(n):
    # random password
    #uses decimal ascii values
    s = []
    for i in range(n):
        j = random.randint(1,4)  # select category
        match j:
            case 1:  # upper case
                lo = 65
                hi = 90
            case 2:  # lower case
                lo = 97
                hi = 122
            case 3:  # numeric
                lo = 48
                hi = 57
            case 4:  #none alp0ha numeric
                lo = 33
                hi = 47                
                         
        rand_ascii = random.randint(lo, hi)  #select character
        s.append(chr(rand_ascii))
       
    return s   

x = pwd_gen(N)
for i in range(N):
    print(x[i],end=" ")
As an aside, password hygiene has changed since. The recommended model is to take a large dictionary and generate a small series of words, as (vocabulary^(3~5)*alphanumeric^(2~5)) is both more secure and easily remembered than (alphanumeric^(8~16))
 
Security has to do with the number of combinations. Whether it is words from a dictionary or random numbers.

I was thinking a series of long signed integers. 10 numbers would have an enormous number of combinations and easy to remember.

-10000 +1045321 +985643287 .....


Interesting idea, but I would think it could end up with people using familiar words like their pet cat and dog names or their kids' names.

How about antidisestablishmentarianism.

I think AI might have easier hack than with random chatterers.
 
Security has to do with the number of combinations. Whether it is words from a dictionary or random numbers.

I was thinking a series of long signed integers. 10 numbers would have an enormous number of combinations and easy to remember.

-10000 +1045321 +985643287 .....


Interesting idea, but I would think it could end up with people using familiar words like their pet cat and dog names or their kids' names.

How about antidisestablishmentarianism.

I think AI might have easier hack than with random chatterers.
This is why you "diceware" over the "vocabulary": load a dictionary file with all of the permutations listed per root word (go, going, gone goner, goes...), and then select a chain.

This way, the person doesn't select the password and gets something like "BeBlueFortHousingTorpedoes359".

The length also forces a brute force attack to involve INSANELY long rainbow tables, taking that method of password hacking out of feasibility
 
Security has to do with the number of combinations. Whether it is words from a dictionary or random numbers.
As always, a little knowledge is a dangerous thing.

I wish I had a dollar for every person who thinks they know all about security; And if I were less ethical, I could probably take one from each of them, too.
 
The Oxford dictionary would be a good choice. Before Internet I had a hard copy. Fine printt, it came with a magnifying glass.

AI Overview
The Oxford English Dictionary contains over 600,000 word and phrase forms, including 171,476 words currently in use and 47,156 obsolete words in its complete print edition.

Largest Dictionaries by Word Count
Tamil (Sorkuvai): ~1,552,065 headwords (run by the Tamil Nadu government).Korean (Urimalsaem): ~1,186,764 headwords (an open government database including regional dialects).
English (English Wiktionary): ~923,306 headwords (with over 1.4 million total entries).
Portuguese (Aulete Digital): ~818,000 entries and expressions.Finnish (RedFox Pro): ~800,000 words (combining technical and generalized glossaries).

For password security it comes down to how many ombinations there are to try, regardless of random sequences or stinging words together.

That is why using the full number of ASCII printable charters for a password character increases securty.

Then there is encryption.

AI Overview
Accessing websites or servers using public-private encryption keys involves matching a secret private key on your device with an authorized public key on the remote system to prove your identity without a password

My email site offers dual authentication, but I do not use it. I have no personal information on the site or in emails that can cause me problems. I use dual authentication for other sites.

The code was something to do and may be of interest to some lurkers.
 
Last edited:
For the uninitiated concerning only password security from a computer keyboard on the net.

Consider a two chat6cter password. Each character in the password is either a or b.

The possibilities are
a a
a b
b a
b b

It takes only 4 tries to get in.

A four digit PIN has four digits each from 0-9.

0 0 0 0
0 0 0 1
.
.
.
9 9 9 9


You can look up passwords and combinatorics and the permutations/combinations equations.

Using the entire range of ASCII printable characters for each charier in a password has 93 possibilities for each character. Plug it into an online calculator. Compare it to using just alpha numerics for an eight catcher password.
 
Back
Top Bottom