SuperGenPass is great

I'm a big fan of SuperGenPass so I decided to learn how it works. The algorithm is pretty simple so I decided to implement it in two of my favorite languages: PHP and Perl.

Hopefully this will help someone else trying to understand the concepts. Special thanks to Iannz for the great Bash implementation I based my code on.

Leave A Reply

Perl: Array of all regexp captures

Perl v5.25.7 added support for the @{^CAPTURE} variable which wrapped all the regexp parenthesis captures up into an array. If you need this functionality in a version of Perl older than that you can use this function:

my $str =  "Hello Jason Doolis";
$str    =~ /Hello (\w+) (\w+)/;

my @captures = get_captures(); # ("Jason", "Doolis")
sub get_captures {
    my $str      = $&;
    my @captures = ();

    # Build array using the offsets from @- and @+
    for (my $i = 1; $i < @-; $i++) {
        my $start = $-[$i];
        my $end   = $+[$i];
        my $len   = $end - $start;

        my $str = substr($str, $start, $len);
        push(@captures, $str);
    }

    return @captures;
}
Leave A Reply

PHP: Creation of dynamic property Class::$Var is deprecated

I upgraded to PHP 8.2 today and started getting a lot of Creation of dynamic property Class::$Var is deprecated errors. This is just PHP's way of telling you that you need to pre-declare your class variables before you use them. To me this just meant adding a lot of:

class user {
    var $name  = "";
    var $id    = 0;
    var $perms = [];

to the tops of my classes. This is the right way to fix things, and what I did in 99% of the cases where I was seeing this error.

However I do have a couple of classes where it's necessary to be able to add dynamic properties on the fly, and PHP does offer a work around for this. If you use a special declaration immediately before your class statement PHP will allow dynamic properties to be added without throwing any errors.

#[\AllowDynamicProperties]
class user {

Note: The \ in the brackets is required

Leave A Reply

Arduino: Using an ATX power supply as a hobbyist power source

Running some RGB LEDs had me thinking about alternate sources of power. Specifically I need a mix of +5v and +12v to power different types of LEDs. Old ATX computer power supplies are a good/cheap source of power because they are easy to harvest from old PCs. They're also usually rated for high wattage.

After some research I found that you need to do a little work to turn on a PC power supply that's not hooked up to a motherboard. Specifically you need to short the green PS-ON pin to ground. This simulates pressing the power button on your PC and triggers the supply to turn on. You can tell the power supply is on when the fan starts to spin. This can be accomplished by cutting the green and (any) black wire out of the ATX connector and connecting them together.

Alternately the power supply will supply +5v of power even in off or standby mode if you use the purple +5vSB line. If all you need is a small amount (less than 2 amps) of 5v power using the +5vSB line is a great alternative and will be quieter because the fan will not be on.

Once the power supply is on you can use the other wires as follows:

Color Type
Black Ground
Orange +3.3v
Red +5v
Yellow +12v

Other pins are less useful but available:

Color Type
Green Power Supply On
Blue -12v
White -5v
Purple +5v standby

Be sure to check the amperage ratings for each voltage on the side of your power supply before use.

Leave A Reply

PHP: Serializing data to save it for caching

I need to cache some data to disk between PHP requests so I decided to compare the various methods available.

Using 100000 element array as source data

Serialize save: 2.958 ms (1.5M)
Serialize read: 5.447 ms

JSON save: 1.880 ms (574.96K)
JSON read: 6.876 ms

PHP save: 8.684 ms (1.7M)
PHP read: 26.863 ms

Memcache set: 5.651 ms
Memcache get: 2.465 ms

IGBinary save: 1.377 ms (720.08K)
IGBinary read: 2.245 ms

MsgPack save: 1.389 ms (359.92K)
MsgPack read: 2.930 ms

I was surprised to see IGBinary and MsgPack so much faster than native JSON. JSON is easy and super portable, but not the fastest.

Leave A Reply

Linux: repeatedly run a command to monitor output

If you need to repeatedly run a command and view the output changes over time then check out my cli_watch.pl script. I was watching a RAID array rebuild slowly and needed a way to see the progress over time.

Usage: cli_watch.pl [--delay 15] [--line 3] command

Run my_command every 15 seconds:

cli_watch.pl --delay 15 'my_command | grep stuff'

Filter output to only line 2:

cli_watch.pl --line 2 'ping -c 1 192.168.5.222'

Leave A Reply - 1 Reply

Perl: Add an element to the middle of an array

If you want to add an element to the middle of an existing array you can use the splice() function. Splice modifies arrays in place. Splice takes four arguments for this: the array to modify, the index of where you want to modify, the number of items you want to remove, and an array of the elements to add.

my @x = qw(one three);

# At the 2nd index, add (replace zero elements) a one element array
splice(@x, 1, 0, ('two'));

print join(" ", @x); # "one two three"
Leave A Reply

Perl: Get certain elements of an array the lazy way

I learned that you can extract various elements from a Perl array in a very creative/simple way. Using this syntax may simplify some of your code and save you a lot of time.

my @colors = ("red", "blue", "green", "yellow", "orange", "purple");

my @w = @colors[(0, 3)];    # ("red", "yellow");
my @x = @colors[(0, 2, 4)]; # ("red", "green", "orange");

# First and last element
my @y = @colors[(0, -1)];   # ("red", "purple");

# First ten items
my @z = @array[0 .. 10];    # Using the `..` range operator

Basically any call to an array where the payload is an array of indexes will return a new array with those items extracted.

my @colors = ("red", "blue", "green", "yellow", "orange", "purple");

# You can also use an array variable to specify the elements to extract
my @ids = (1,3,5);
my @x   = @colors[@ids]; # ("blue", "yellow", "purple")

Note: Since you are referencing the whole array (not one element) you use the @ sigil instead of $.

Leave A Reply

Nagios: Check free memory on a Linux server

I had a Linux server run low on free memory which caused some processes to stop responding. Surprisingly there isn't a good modern Nagios plugin to check free memory so I wrote my own to watch for this in the future. Pretty basic, but it works well.

Leave A Reply

PHP: Stopwatch function to time pieces of code

I need to time how long a certain piece of code takes to complete. I wrote a simple PHP stopwatch function to accomplish this:

sw(); // Start the stopwatch
$x  = some_slow_code();
$ms = sw(); // Return milliseconds since start
// Stopwatch function: returns milliseconds
function sw() {
    static $start = null;

    if (!$start) {
        $start = hrtime(1);
    } else {
        $ret   = (hrtime(1) - $start) / 1000000;
        $start = null; // Reset the start time
        return $ret;
    }
}
Leave A Reply

Lumens per watt as required by the government

New laws have gone in to place that govern the amount of energy used to generate light:

The rule passed by President Joe Biden’s Department of Energy in April 2022 states that light bulbs must emit a minimum of 45 lumens per watt. A lumen is a measure of brightness.

That effectively outlaws the manufacture and sale of common incandescent bulbs, the kind you screw into the vast majority of light sockets in your home. That’s because traditional incandescent bulbs provide just 15 lumens per watt, according to light bulb manufacturer Philips.

By contrast, most LED bulbs will get you 75 lumens per watt, or more.

Further restrictions will take place in 2024 as well:

In December 2022, the Department of Energy proposed a rule that would more than double the current minimum light bulb efficiency level, to over 120 lumens per watt for the most common bulbs. That would go into effect by the end of 2024 and effectively ban CFL bulbs.

Leave A Reply

Python: Null coallesce on an array

I have a small array in Python, and I need to get the 2nd element of that array, or a default value if it's not present. All the other languages (PHP, Perl, Javascript) I use have a simple null coallescing operator that makes it simple, but not Python. I got tired of writing it out every time to so I wrote a simple wrapper function:

x = [2,4,6]

# Get the 3rd item from x
y = arrayItem(2, x, -1) # 6
# Get the 8th (non-existent) item from x
y = arrayItem(7, x, -1) # -1
# Get an item from an array, or a default value if the array isn't big enough
def arrayItem(needle, haystack, default = None):
    if needle > (len(haystack) - 1):
        return default
    else:
        return haystack[needle]

If there is a better, simpler, built-in way I'm open to hearing it.

Leave A Reply - 1 Reply

Linux: fd is a much better file search

Linux has had the find command since the 1970s. It was probably great in it's day, but it's not very modern and isn't the most intuitive tool. I found fd (sometimes called fd-find) which is infinitely better and easier to use. If you're looking for a simple way to search your filesystem, it's the way to go.

fd-find is hosted on Github.

Leave A Reply

Arduino: Get IP and MAC address

Here is a quick way to get the IP address and/or MAC address from your Arduino device as a String.

String get_mac_addr() {
    uint8_t mac[6];
    WiFi.macAddress(mac); // Put the addr in mac

    char buf[18] = "";
    snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

    return (String)buf;
}
String get_ip_addr() {
    IPAddress ip = WiFi.localIP();

    char buf[16];
    snprintf(buf, sizeof(buf), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);

    return (String)buf;
}
Leave A Reply

Arduino: Connect to WiFi

Quicky helper function to connect to WiFi on Arduino so I don't have to re-invent the wheel every time I start a new project.

void init_wifi(const char *ssid, const char *password) {
    WiFi.mode(WIFI_STA); WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500); Serial.print(".");
    }

    Serial.printf("\r\nConnected to: \"%s\"\r\n",ssid);
    Serial.print("IP address  : "); Serial.println(WiFi.localIP());
    Serial.print("MAC address : "); Serial.println(WiFi.macAddress().c_str());
}
Leave A Reply