<?php

/*
 * Logical functions to convert character case
 *
 * Paul Gregg <pgregg@pgregg.com>
 * 4th August 2005
 * Copyright 2005, Paul Gregg
 *
 * Open Source Code:   If you use this code on your site for public
 * access (i.e. on the Internet) then you must attribute the author and
 * source web site: http://www.pgregg.com/projects/php/code/str_case.phps
 *
 * Motivation, I saw a monstrosity of string case invert and randomise
 * on the php str_shuffle man page using for loops through each character
 * and knew I could do it using beautiful bitwise logic.
 *
 * With thanks to arpad who took my solution and provided a single line
 * solution.
 *
 * Code broken down to show how it works
  // Code that will invert the case of every character in $input
    // The solution is to flip the value of 3rd bit in each character
    // if the character is a letter. This is done with XOR against a space (hex 32)
    $stringmask = preg_replace("/[^a-z]/i", chr(0), $input); // replace nonstrings with NULL
    $stringmask = preg_replace("/[a-z]/i", ' ', $stringmask); // replace strings with space
    return $input ^ $stringmask;

  // Code that will randomise the case of every character in $input
    $stringmask = preg_replace("/[^a-z]/i", chr(0), $input);
    $stringmask = preg_replace("/[a-z]/i", ' ', $stringmask);
    // make a hex 32 mask of random number chars
    $invertmask = str_pad('', mt_rand(0,strlen($input)), ' ');
    // now pad it out to the string length with NULL and shuffle
    $invertmask = str_shuffle(str_pad($invertmask, strlen($input), chr(0)));
    return $input ^ ($invertmask & $stringmask);
  }
 */


define('STRCASE_NULL',   0);
define('STRCASE_INVERT', 1);
define('STRCASE_RAND',   2);
define('STRCASE_UPPER',  3);
define('STRCASE_LOWER',  4);


Function str_case($input, $method=0) {

  switch($method) {
    case STRCASE_INVERT:
      return preg_replace('/[a-z]+/ie', '\'$0\' ^ str_pad(\'\', strlen(\'$0\'), \' \')', $input);
      break;

    case STRCASE_UPPER:
      return preg_replace('/[a-z]+/e', '\'$0\' & str_pad(\'\', strlen(\'$0\'), chr(223))', $input);
      break;

    case STRCASE_LOWER:
      return preg_replace('/[A-Z]+/e', '\'$0\' | str_pad(\'\', strlen(\'$0\'), \' \')', $input);
      break;

    case STRCASE_RAND:
      return preg_replace('/[a-z]/ie', '(rand(0,1) ? \'$0\' ^ \' \' : \'$0\')', $input);
      break;

    default:
      return $input;
      break;
  }

}


$inputs = array(
    "Hello, this is a test.",
    "Hi. Do you like this?",
    "Hi to the rest of PHP.",
    "Another test message"
    );

print "<pre>";
printf("%-25s %-25s %-25s %-25s %-25s\n",
    'Input', 'Inverted', 'Upper', 'Lower', 'Randomised');

foreach ($inputs as $input) {
  printf("%-25s %-25s %-25s %-25s %-25s\n",
    $input,
    str_case($input, STRCASE_INVERT),
    str_case($input, STRCASE_UPPER),
    str_case($input, STRCASE_LOWER),
    str_case($input, STRCASE_RAND));
}

?>