Railsbin – The vulnerable pastebin service!

User:

Title: secret

Content:

<?php
function str_last_char(string $s): string
{
	$len = strlen($s);
	return $len ? $s[$len-1] : '';
}

function get_tbs_solution()
{
	if ($solution = GWF_Session::get('tbs_revival_solution'))
	{
		return $solution;
	}
	$solution = GWF_Random::randomKey(16);
	GWF_Session::set('tbs_revival_solution', $solution);
	return $solution;
}

function check_tbs_solution(string $answer)
{
	$solution = get_tbs_solution();
	return strcasecmp($answer, $solution) === 0;
}

define('TBS_CHARSET', 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz');
define('SPACE', '+');
define('IGNORE', ' ');

function get_tbs_diff(string $a, string $b): int
{
	$a = strtolower($a);
	$b = strtolower($b);
	$a = preg_replace('/[^a-z]/', '', $a);
	$b = preg_replace('/[^a-z]/', '', $b);
	$la = strlen($a);
	$lb = strlen($b);
	$min = min([$la, $lb]);
	$diff = 0;
	for ($i = 0; $i < $min; $i++)
	{
		$ca = $a[$i];
		$cb = $b[$i];
		$oa = ord($ca);
		$ob = ord($cb);
		$d1 = abs(strpos(TBS_CHARSET, $ca) - strpos(TBS_CHARSET, $cb));
		$d2 = abs(strpos(TBS_CHARSET, $ca) - strrpos(TBS_CHARSET, $cb));
		$d = min([$d1, $d2]);
		$diff += $d;
	}
	$diff += abs($la - $lb);
	return $diff;
}

function get_tbs_message()
{
	$message = require_once 'secret_message.php';
	$message = trim($message); '';
	$user = GWF_User::getStaticOrGuest();
	if (!$user->isGuest())
	{
		$message = $user->displayUsername() . ", " . $message;
		$solution = get_tbs_solution();
		$message .= 'Solution: ' . $solution;
	}
	return $message;
}

function tbs_encode(string $message, array $carry): array
{
	if ($encoded = GWF_Session::get('tbs_revival_encoded'))
	{
// 		return $encoded;
	}
	$encoded = encode($message, $carry);
	$encoded[0] = tbs_herringed($encoded[0]);
	GWF_Session::set('tbs_revival_encoded', $encoded);
	return $encoded;
}

function tbs_herringed(string $encoded): string
{
	$encoded = preg_replace('/ ([0-9])/', '*$1', $encoded);
	$encoded = preg_replace('/   /', ' / ', $encoded);
	$encoded = preg_replace_callback('/ /', function(array $match){
		return rand(0, 1) ? ' ' : '^';
	}, $encoded);
// 	$encoded = preg_replace('/\\^ /', '^0', $encoded);
// 	$encoded = preg_replace('/\\+ /', '+1', $encoded);
	return $encoded;
}

function encode(string $message, array $carry): array
{
	$i = 0;
	$j = 0;
	$k = 0;
	$len = strlen($message);
	$word = '';
	$wlen = strlen($word);
	$cin = ' TBS STILL LIVES! ';
	$len2 = strlen($cin);
	$out = '';
	$cout = ' TBS STILL LIVES! ';
	$prev = ' ';
	while ($i < $len)
	{
		if ($k >= $wlen)
		{
			$word = _next_word($word, $message, $i);
			$wlen = strlen($word);
			$k = 0;
		}
		if ($j >= $len2)
		{
			$cin = _next_carry($carry, $word);
			if (!$cin)
			{
				$out .= 'CHALLENGE_IS_BROKEN!!!';
				$cout .= 'CHALLENGE_IS_BROKEN!!!';
				break;
			}
			$cout .= $cin;
			$len2 = strlen($cin);
			$j = 0;
		}
		
		$ic = $word[$k]; # input char
		$cc = $cin[$j++]; # carry char
		
		$enc = _next_char($ic, $cc, $prev, $out);
		if ($enc)
		{
			$i++;
			$k++;
		}
		$prev = str_last_char($out);
	}
	return [$out, $cout];
}


function _next_word(string $word, string $message, int $i): string
{
	$message = substr($message, $i);
	$matches = null;
	preg_match('/(\w+[^\w]*)/', $message, $matches);
	return $matches[1];
}

function _next_carry(array &$carry, string $in): ?string
{
	static $first = true;
	$min = PHP_INT_MAX;
	$minkey = null;
	$minword = null;
	$len = strlen($in);
	foreach ($carry as $key => $word)
	{
		if (strlen($word) >= $len)
		{
			$dist = get_tbs_diff($word, $in);
			if ($dist < $min)
			{
				$min = $dist;
				$minkey = $key;
				$minword = $word;
			}
		}
	}
	if ($minword)
	{
		unset($carry[$minkey]);
	}
	
// 	if ($first)
// 	{
// 		$first = false;
// 		return $minword;
// 	}
	
	return "$minword";
}

function _carry_can_encode(string $carry, string $in)
{
	return ctype_alpha($carry);
}

function _input_is_literal(string $in): bool
{
	return !ctype_alpha($in);
}

### Carrier
### Secret
###-4  04
function _next_char(string $in, string $carry, string $prev, string &$out): bool
{
   	$encodable = false;
   	
   	if ($in === ' ')
   	{
   		$out .= SPACE;
   		$encodable = true;
   	}
   	elseif (_input_is_literal($in))
   	{
   		$out .= $in;
   		$encodable = true;
   	}
   	elseif (!_carry_can_encode($carry, $in))
   	{
   		$out .= IGNORE;
   	}
   	else
   	{
   		# Encodable?
		$diff = get_tbs_diff($in, $carry);
		$encodable = $diff < 9;
		if ($encodable)
		{
			if (strcasecmp($in, $carry) < 0)
			{
				if ($prev !== ' ')
				{
					$out .= IGNORE;
					return false;
				}
				else
				{
					$outpos = strlen($out);
					$out[$outpos - 1] = '-';
				}
			}
		}
		if ($encodable)
		{
			$out .= $diff;
		}
		else
		{
			$out .= IGNORE;
		}
   	}
	return $encodable;
}

function decode(array $carry, string $encoded): string
{
	# @TODO implement ;)
}

Edit | Back