Bot::Cobalt::Utils - Utilities for Cobalt plugins


Bot::Cobalt::Utils provides a set of simple utility functions for the Bot::Cobalt core and plugins.

Plugin authors may wish to make use of these; importing the :ALL tag from Bot::Cobalt::Utils will give you access to the entirety of this utility module, including useful string formatting tools, safe password hashing functions, etc.

You may also want to look at Bot::Cobalt::Common, which exports most of this module.


Import nothing:

  use Bot::Cobalt::Utils;
  my $hash = Bot::Cobalt::Utils::mkpasswd('things');

Import some things:

  use Bot::Cobalt::Utils qw/ mkpasswd passwdcmp /;
  my $hash = mkpasswd('things');

Import all the things:

  use Bot::Cobalt::Utils qw/ :ALL /;
  my $hash = mkpasswd('things', 'sha512');
  my $secs = timestr_to_secs('3h30m');
  . . .

See below for a list of exportable functions.


Exportable functions

"timestr_to_secs" - Convert a string into seconds
"secs_to_timestr" - Convert seconds back into timestr
"secs_to_str" - Convert seconds into a 'readable' string
"color" - Add format/color to IRC messages
"glob_to_re_str" - Convert Cobalt-style globs to regex strings
"glob_to_re" - Convert Cobalt-style globs to compiled regexes
"glob_grep" - Search an array or arrayref by glob
"rplprintf" - Format portable langset reply strings
"mkpasswd" - Create crypted passwords
"passwdcmp" - Compare crypted passwords

Date and Time


Convert a string such as "2h10m" into seconds.

  my $delay_s = timestr_to_secs '1h33m10s';

Useful for dealing with timers.


Turns seconds back into a timestring suitable for feeding to "timestr_to_secs":

  my $timestr = secs_to_timestr 820; ## -> 13m40s


Convert a timestamp delta into a string.

Useful for uptime reporting, for example:

  my $delta = time() - $your_start_TS;
  my $uptime_str = secs_to_str $delta;

Returns time formatted as: <D> day(s), <H>:<M>:<S>


Like "secs_to_str", but includes year calculation and returns time formatted as: <Y> year(s), <D> day(s), <H>:<M>:<S> if there are more than 365 days; otherwise the same format as "secs_to_str" is returned.

(Added in v0.18.1)

String Formatting


Add mIRC formatting and color codes to a string.

Valid formatting codes:


Valid color codes:


Format/color type can be passed in upper or lower case.

If passed just a color or format name, returns the control code.

If passed nothing at all, returns the 'NORMAL' reset code:

  my $str = color('bold') . "bold text" . color() . "normal text";

If passed a color or format name and a string, returns the formatted string, terminated by NORMAL:

  my $formatted = color('red', "red text") . "normal text";

If you need to retrieve (or alter via local, for example) the actual control characters themselves, they are accessible via the %Bot::Cobalt::Utils::COLORS hash:

  my $red = $Bot::Cobalt::Utils::COLORS{RED}


glob_to_re_str() converts Cobalt-style globs to regex strings.

  my $re = glob_to_re_str "th?ngs*stuff";
  ## or perhaps compile it:
  my $compiled_re = qr/$re/;

Perl regular expressions are very convenient and powerful. Unfortunately, that also means it's easy to make them eat up all of your CPU and thereby possibly break your system (or at least be annoying!)

For string search functions, it's better to use Cobalt-style globs:

  * == match any number of any character
  ? == match any single character
  + == match any single space
  leading ^  == anchor at start of string
  trailing $ == anchor at end of string

Standard regex syntax will be escaped and a translated regex returned.

The only exception is character classes; this is valid, for example:



glob_to_re() converts Cobalt-style globs to compiled regexes (qr//)

Using a compiled regex for matching is faster. Note that compiled regexes can also be serialized to YAML using Bot::Cobalt::Serializer.

See "glob_to_re_str" for details on globs. This function shares the same syntax.


glob_grep() can be used to search an array or an array reference for strings matching the specified glob:

  my @matches = glob_grep($glob, @array) || 'No matches!';
  my @matches = glob_grep($glob, $array_ref);

Returns the output of grep, which will be a list in list context or the number of matches in scalar context.


rplprintf() provides string formatting with replacement of arbitrary variables.

  rplprintf( $string, %vars_hash );
  rplprintf( $string, $vars_ref  );

The first argument to rplprintf should be the template string. It may contain variables in the form of %var or %var% to be replaced.

The second argument is the hash (or hash reference) mapping %var variables to strings.

For example:

  $string = "Access denied for %user (%host%)";
  $response = rplprintf(  $string,
      user => "Joe",
      host => "joe!",
  ## $response = 'Access denied for Joe (joe!'

Intended for formatting langset RPLs before sending, but can be used for any simple string template.

Variable names can be terminated with a space or % -- both are demonstrated in the example above. You'll need to terminate with a trailing % if there are non-space characters following, as in the above example: (%host%)

The same color/format strings as "color" can be applied via %C_* vars:

  $string = "Access %C_BOLD%denied%C_NORMAL";
  $response = rplprintf( $string );

Password handling


Simple interface for creating hashed passwords.

Defaults to creating a password using Crypt::Eksblowfish::Bcrypt with a random salt and bcrypt work cost '08' -- this is a pretty sane default.

See App::bmkpasswd for details; the built-in hash generation sugar was moved to that package.

bcrypt is strongly recommended; SHA and MD5 methods are also supported. Salts are always random.

  ## create a bcrypted password (work cost 08)
  ## bcrypt is blowfish with a work cost factor.
  ## if hashes are stolen, they'll be slow to break
  ## see
  my $hashed = mkpasswd $password;

  ## you can specify method options . . .
  ## here's bcrypt with a lower work cost factor.
  ## (must be a two-digit power of 2, possibly padded with 0)
  my $hashed = mkpasswd $password, 'bcrypt', '06';

  ## Available methods:
  ##  bcrypt (preferred)
  ##  SHA-256 or -512 (req. modern libc or Crypt::Passwd::XS)
  ##  MD5 (fast, portable, weak)
  my $sha_passwd = mkpasswd $password, 'sha512';
  ## same as:
  my $sha_passwd = mkpasswd $password, 'SHA-512';


Compare hashed passwords via App::bmkpasswd.

Compatible with whatever methods mkpasswd supports on the current system.

  return passwdcmp $password, $hashed;

Returns the hash if the cleartext password is a match. Otherwise returns boolean false.


Jon Portnoy (avenj)