<?php
/*
--------------------------------------------------------------------------
Geodetic Distance Calculator
This program computes the geodetic surface distance between two points on
Earth given their respective latitudes and longitudes.
It is based on the Andoyer Algorithm and theoretically accurate to the
nearest 0.1 km.
Author:
Jay Tanner - 2025
Current Web Site
www.NeoProgrammics.com
AUTHOR : Jay Tanner - 2025
LANGUAGE : PHP v8.2.12
LICENSE : Public Domain
--------------------------------------------------------------------------
*/
ob_start();
// -----------------------------------
// Get current year from system clock.
$cYear = date('Y');
/* ------------------------------------------
Define program version and revision dates.
*/
$ProgramVersion = "v1.13";
$RevisionDate = "2020-May-19-Tue";
$ReKm = 6378.137;
$ReMi = 3963.191;
$ReNmi = sprintf("%1.3f", $ReKm / 1.852);
$flattening = "1/298.257";
list($u, $w) = preg_split("[\/]", $flattening);
$f = $u/$w;
// COMPUTE POLAR RADIUS OF THE EARTH FROM THE
// FLATTENING AND THE EQUATORIAL RADIUS.
$RpKm = 6378.137 * (1 - $f);
$RpMi = sprintf("%1.3f", $RpKm / 1.609344);
$RpNmi = sprintf("%1.3f", $RpKm / 1.852);
$RpKm = sprintf("%1.3f", $RpKm);
$f = sprintf("%1.9f", $f);
$OutputText = '';
// Define status message to be displayed in TEXTAREA while working.
$StatusText1 = "OutputTextArea.innerHTML='COMPUTING ...';";
/* -----------------------------------------------
Set the path to the program to be executed when
any submit button is clicked. In this case, it
is this program itself. It modifies itself each
time it is called.
*/
$RUN_PROGRAM = $_SERVER['SCRIPT_NAME'];
// READ GEOGRAPHIC COORDINATES OF THE TWO POINTS.
$LatLon1 = @$_POST['LatLon1'];
$LatLon2 = @$_POST['LatLon2'];
$Loc1 = @$_POST['Loc1'];
$Loc2 = @$_POST['Loc2'];
if(trim($Loc1) == '') {$Loc1 = "Point A";}
if(trim($Loc2) == '') {$Loc2 = "Point B";}
if(trim($LatLon1) == '' and trim($LatLon2) == '')
{
/*
SELECT DEFAULT RANDOM LOCATION COORDINATES.
*/
$Loc1 = "Point A";
$LatLon1 = 90*Rand_Decimal(16, TRUE) . ', ' . 180*Rand_Decimal(16, TRUE);
$Loc2 = "Point B";
$LatLon2 = 90*Rand_Decimal(16, TRUE) . ', ' . 180*Rand_Decimal(16, TRUE);
// OVERRIDE DEFAULTS ABOVE
$Loc1 = "Washington, DC, USA";
$LatLon1 = '+38.9213889; -77.0655556';
$Loc2 = "Paris, France";
$LatLon2 = '+48.8363889; +2.3372222';
/*
$Loc1 = "Rubha na Lice, Mull of Kintyre, Mean High Water Springs, Scotland";
$LatLon1 = "+55.299691653, -5.799218022";
$Loc2 = "Torr Head, Antrim, Ireland";
$LatLon2 = "+55.198861053, -6.062220511";
*/
/*
$Loc1 = "Paris, France";
$LatLon1 = "+48.8363889, +2.3372222";
$Loc2 = "Washington, DC, USA";
$LatLon2 = "+38.9213889, -77.0655556";
*/
}
$w1 = Process_Lat_Lon_String($LatLon1);
$w2 = Process_Lat_Lon_String($LatLon2);
// PARSE INDIVIDUAL COORDINATES VALUES.
list($lat1, $lon1) = preg_split("[ ]", $w1);
list($lat2, $lon2) = preg_split("[ ]", $w2);
// FORMAT FOR DISPLAY.
$latDMS1 = Deg_to_DMS($lat1, 3, '+', 'd');
$lonDMS1 = Deg_to_DMS($lon1, 3, '+', 'd');
$latDMS2 = Deg_to_DMS($lat2, 3, '+', 'd');
$lonDMS2 = Deg_to_DMS($lon2, 3, '+', 'd');
$LatLon1 = "$lat1, $lon1";
$LatLon2 = "$lat2, $lon2";
$DoneFlag = FALSE;
if ($lat1 == $lat2 and $lon1 == $lon2)
{
$OutputText =
"
GEODETIC DISTANCE BETWEEN TWO LOCATIONS ON THE EARTH SPHEROID
Based on the Andoyer Algorithm (to nearest ±0.1 km)
FIRST LOCATION: $Loc1
Latitude = $lat1 ° \t= $latDMS1
Longitude = $lon1 ° \t= $lonDMS1
----------------------------------------------------------------------
SECOND LOCATION: $Loc2
Latitude = $lat2 ° \t= $latDMS2
Longitude = $lon2 ° \t= $lonDMS2
----------------------------------------------------------------------
THE GEODETIC DISTANCE BETWEEN THE LOCATIONS:
kilometers, statute miles and nautical miles
0.0 km = 0.0 mi = 0.0 nmi
Both points are at the same coordinates. There is no distance between
them.
";
$DoneFlag = TRUE;
}
if ($DoneFlag === FALSE)
{
// FORMAT FOR DISPLAY.
$latDMS1 = Deg_to_DMS($lat1, 3, '+', 'd');
$lonDMS1 = Deg_to_DMS($lon1, 3, '+', 'd');
$latDMS2 = Deg_to_DMS($lat2, 3, '+', 'd');
$lonDMS2 = Deg_to_DMS($lon2, 3, '+', 'd');
$DistKm = Geodetic_Dist ($lat1,$lon1, $lat2,$lon2); // km output
$DistMi = $DistKm / 1.609344;
$DistNMi = number_format($DistKm/1.852, 1);
$DistKm = number_format($DistKm, 1);
$DistMi = number_format($DistMi, 1);
$lat1 = RTrim(RTrim($lat1, '0'), '.');
$lat2 = RTrim(RTrim($lat2, '0'), '.');
$lon1 = RTrim(RTrim($lon1, '0'), '.');
$lon2 = RTrim(RTrim($lon2, '0'), '.');
$LatLon1 = "$lat1 ; $lon1";
$LatLon2 = "$lat2 ; $lon2";
// COMPUTE THEORETICAL MAXIMUM MARGIN OF ERROR
// BASED ON THE DISTANCE BETWEEN THE POINTS.
$MoEkm = (floatval($DistKm) / 20037.508) * 0.05;
$MoEmi = $MoEkm / 1.609344;
$MoEnmi = $MoEkm / 1.852;
// FORMAT FOR DISPLAY.
$MoEkm = sprintf("%1.3f", $MoEkm);
$MoEmi = sprintf("%1.3f", $MoEmi);
$MoEnmi = sprintf("%1.3f", $MoEnmi);
$NS1 = ($lat1 < 0)? '(S) ':'(N) '; if ($lat1 == 0) {$NS1 = '(•) ';}
$NS2 = ($lat2 < 0)? '(S) ':'(N) '; if ($lat2 == 0) {$NS2 = '(•) ';}
$EW1 = ($lon1 < 0)? '(W) ':'(E) '; if ($lon1 == 0) {$EW1 = '(•) ';}
$EW2 = ($lon2 < 0)? '(W) ':'(E) '; if ($lon2 == 0) {$EW2 = '(•) ';}
$OutputText =
"
GEODETIC DISTANCE BETWEEN TWO LOCATIONS ON THE EARTH SPHEROID
Based on the Andoyer Algorithm (to nearest ±0.1 km)
1st LOCATION = $Loc1
Latitude = $NS1$lat1° \t= $latDMS1
Longitude = $EW1$lon1° \t= $lonDMS1
----------------------------------------------------------------------
2nd LOCATION = $Loc2
Latitude = $NS2$lat2° \t= $latDMS2
Longitude = $EW2$lon2° \t= $lonDMS2
----------------------------------------------------------------------
THE GEODETIC DISTANCE BETWEEN THE LOCATIONS:
kilometers, statute miles and nautical miles
$DistKm km = $DistMi mi = $DistNMi nmi
";
$DoneFlag = TRUE;
}
// DETERMINE HOW MANY ROWS TO USE FOR THE OUTPUT TEXTAREA.
$TextRows = 2 + substr_count($OutputText, "\n");
print <<< _HTML
<!DOCTYPE HTML>
<html lang='en'>
<head>
<title>Geodetic Distance Between Any Two Points On Earth Spheroid</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<meta http-equiv='content-type' content='text/html; charset=UTF-8'>
<meta name='description' content='This program computes the geodetic distance between any two points on the Earth spheroid based on the Andoyer algorithm.'>
<meta name='keywords' content='Andoyer algorithm,Andoyer,geodesic distance,geodesic,Earth geodesic,distance between points on Earth'>
<meta name='author' content='Jay Tanner - PHPScienceLabs.com'>
<meta http-equiv='pragma' content='no-cache'>
<meta http-equiv='expires' content='-1'>
<meta name='robots' content='index,follow'>
<meta name='googlebot' content='index,follow'>
<link rel="canonical" href="https://www.phpsciencelabs.com/earth-geodetic-distance-calculator/">
<style type='text/css'>
BODY {color:silver; background-color:black; font-family:Verdana; font-size:16px}
TABLE {font-size:12px; border: 1px solid black;}
TD {color:black; background-color:white; line-height:155%; font-size:11px; padding:6px; text-align:center;}
DIV {color:black; background-color:white; font-family:Verdana; text-align:justify; padding:4px; font-size:16px;}
PRE {color:black; background-color:white; font-family:monospace; font-size:15px; font-weight:bold; text-align:left; padding:4px; border-radius:8px;}
CODE {font-family:Consolas,monospace; font-size:15px; font-weight:normal;}
TEXTAREA {color:black; background-color:white; font-family:monospace; font-size:155%; font-weight:bold; padding:8px; box-shadow:4px 4px 3px #888888; border-radius:8px; border:1px solid black; padding:4px; white-space:pre;}
INPUT[type="text"]::-ms-clear {width:0; height:0;}
INPUT[type="text"] {background-color:white; box-shadow:2px 2px 3px #666666; font-family:monospace; font-size:150%; font-weight:bold; text-align:center; border:2px solid black; border-radius:4px;}
INPUT[type="text"]:focus {background-color:white; box-shadow:2px 2px 3px #666666; font-family:monospace; font-size:150%; border:2px solid blue; text-align:center; font-weight:bold; border-radius:4px;}
INPUT[type="submit"]{font-weight:bold; border:1px solid black; border-radius:4px;}
INPUT[type="submit"]:hover {box-shadow:2px 2px 5px #222222; font-weight:bold; background:cyan; border:1px solid black; border-radius:4px;}
INPUT[type="checkbox"]:checked {box-shadow:2px 2px 3px #222222;}
HR {background-color:black; height:2px; border:0px;}
A:link, A:visited {background-color:transparent; color:blue; font-family:Verdana; font-size:90%; font-weight:bold; text-decoration:none; line-height:150%; padding:2px;}
A:hover, A:active {background-color:transparent; color:red; font-family:Verdana; font-size:90%; font-weight:bold; text-decoration:none; line-height:150%; padding:2px;}
::selection {background-color:yellow; color:black;} /* Only affects IE9+ and Safari */
::-moz-selection {background-color:yellow; color:black;} /* Only affects FireFox and Mozilla */
</style>
</head>
<body>
<form name="form1" method="post" action="$RUN_PROGRAM">
<table align='left' width="800" border="0" cellspacing='1'>
<tr><td colspan="2" style='color:white; background-color:#000066; border:2px solid white; font-size:150%; font-weight:normal; border-radius:8px 8px 0px 0px'>Geodetic Distance Between Any Two Points On the Earth Spheroid<br><span style='font-size:80%;'>Based on the Andoyer Algorithm (theoretical accuracy about ±50 meters)</span><br><span style='font-size:70%;'>PHP Program by Jay Tanner</span></td></tr>
<tr><td style='color:black; background-color:yellow;'><b>1<sup>st</sup> LOCATION</b></td> <td style='color:black; background-color:GreenYellow;'><b>2<sup>nd</sup> LOCATION</b></td></tr>
<tr><td style='color:black; background-color:LightYellow; line-height:175%;'>Optional First Place Name / Label<br><input type="text" name="Loc1" value="$Loc1" size='45' maxlength='68' title="$Loc1"><br><br>Enter <b>1</b><sup>st</sup> <b>Latitude ; Longitude</b> as Deg.ddd or as D M S<input type="text" name="LatLon1" value="$LatLon1" size='35' maxlength='34'></td><td style='color:black; background-color:#CCFFD8; line-height:175%;'>Optional Second Place Name / Label<br><input type="text" name="Loc2" value="$Loc2" size='45' maxlength='68' title="$Loc2"><br><br>Enter <b>2</b><sup>nd</sup> <b>Latitude ; Longitude</b> as Deg.ddd or as D M S<input type="text" name="LatLon2" value="$LatLon2" size='35' maxlength='34'></td></tr>
<tr><td colspan="2">Coordinates Convention: <b>Latitude</b> Neg/Pos = South/North and <b>Longitude</b> Neg/Pos = West/East</td></tr>
<tr><td colspan="2"><input type="submit" value="C O M P U T E" onclick="StatusText1"></td></tr>
<!-- Yellow source code view link. --->
<tr>
<td colspan='2' style='background:transparent; color:black; font-size:10pt;
text-align:center; line-height:200%;'>
<a href='View-Source-Code.php' target='_blank'
style='font-family:Verdana; color:black; background:yellow;
text-decoration:none; border:1px solid black; padding:4px;
border-radius:4px;'>
<span style='font-weight:normal;'>View/Copy PHP Source Code</span> </a>
</td>
</tr>
<tr><td colspan="2" style='background-color:#DDDDDD;'><textarea ID="OutputTextArea" rows="$TextRows" cols='72' readonly='readonly' style='white-space:pre; padding:8px;'>$OutputText</textarea></td></tr>
<tr><td colspan="2">Jay Tanner - $cYear</td></tr>
<tr><td colspan="2" style='background-color:#DDDDDD;'>
<table align='center' style='background-color:#DDDDDD; border:1px solid #DDDDDD;'>
<tr><td style='background-color:#DDDDDD;'>
<pre style='width:700px; color:black; background-color:white; padding:8px; border:1px solid black; box-shadow:4px 4px 3px #888888;'>
GENERAL INFORMATION
The program's initial default startup values are for Washington, DC, USA
and Paris, France.
This program computes the geodetic distance between two locations on the
Earth geoid. The maximum theoretical error is on the order of ±50 meters,
but the computed distance is rounded to the nearest ±0.1 (km|mi|nmi).
---------------------------------------------------------------------------
LATITUDE/LONGITUDE CONVENTIONS
The standard longitude convention is Neg/Pos = West/East.
Everyone essentially knows that when we refer to latitudes, positive means
north and negative means south of the equator. Longitudes are a different
matter and more than one longitude convention can be used.
Although the program was designed with the standard coordinates system in
mind, where negative longitudes are west and positive longitudes are to
the east of Greenwich, if you prefer the opposite convention where east
is negative, then you can use that convention instead. Due to the basic
symmetry of the geoid, either convention will work equally well, so it
doesn't really matter which one you use as long as you're consistent
and apply the same longitude convention to both locations.
---------------------------------------------------------------------------
GEOGRAPHIC COORDINATE FORMATS
Coordinates may be obtained from https://www.gps-coordinates.net
and copied/pasted directly to this program interface in the same
Lat,Lon format as "+46.789, -76.543" and separated by a comma.
The coordinates may be entered as decimal degrees or as degrees,
minutes and seconds, separated by spaces. In either case, the
coordinates are separated by a comma and are not restricted to
purely integer values.
EXAMPLES OF VALID COORDINATE VALUES
+123.456789 = D = 1 element = Degrees only
+12 34.56 = D M = 2 elements = Degrees and Minutes
-00 00 12.345 = D M S = 3 elements = Degrees, Minutes and Seconds
For Paris, France, the coordinates could be entered as:
+48.8363889, +2.3372222
or as
+48 50 11.000, +02 20 14.000
or as
48 50 11, 2 20 14
NOTE:
Different sources may differ on the precise geographic coordinates of some
major world locations. Some places are too large to apply a single set of
fixed coordinates. But certain fixed points can serve as benchmarks.
---------------------------------------------------------------------------
UNITS AND BASIC DATA:
UNITS:
1 Statute mile 1.609344 km
1 Nautical mile 1.852 km
EARTH DATA:
Equatorial Radius $ReKm km = $ReMi mi = $ReNmi nmi
Polar Radius $RpKm km = $RpMi mi = $RpNmi nmi
Polar Flattening $flattening = $f
</pre>
</td></tr></table>
</td></tr>
<tr><td colspan='4' style='color:silver; background-color:black;'>Jay Tanner - $cYear</td></tr>
</table>
</form>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</body>
</html>
_HTML;
/*
// Paris
$lat1 = +48.8363889;
$lon1 = +2.3372222;
// Washington, D.C.
$lat2 = +38.9213889;
$lon2 = -77.0655556;
*/
function Process_Lat_Lon_String($LatLonString)
{
$LatLonStr = Strip_Wspace($LatLonString);
if ($LatLonStr == '') {$LatLonStr = "0.0, 0.0";}
// CONVERT ANY SEMICOLON INTO A COMMA.
$LatLonStr = str_replace(';', ',', $LatLonStr);
// if no comma, then attach ', 0.0' . There must be a
// latitude and longitude value separated by a comma
// or semicolon only.
if (strpos($LatLonStr, ',') === FALSE) {$LatLonStr = "$LatLonStr, 0.0";}
// Split the 'Lat , Lon' coordinates at the comma.
list($LatStr, $LonStr) = preg_split("[,]", $LatLonStr);
$LatStr = trim($LatStr);
$LonStr = trim($LonStr);
// make sure coordinates are in degrees.
$LatStr = DMS_to_Deg($LatStr);
$LonStr = DMS_to_Deg($LonStr);
// RETURN SPACE-DELIMITED SIGNED LAT/LON VALUES
// IN DEGREES ROUNDED TO 9 DECIMALS.
$LatStr = sprintf("%+2.9f", $LatStr);
$LonStr = sprintf("%+3.9f", $LonStr);
return "$LatStr $LonStr";
}
// ---------------------------------------------------------------
// This function computes the geodetic distance between two points
// on the spheroid from their longitude and latitude coordinates
// in degrees.
//
// The distance can be returned in kilometers (default) or miles.
//
// Longitudes assume standard convention (Neg/Pos = West/East),
// but the inverse convention will work equally as well.
//
// Based on the Andoyer Algorithm.
function Geodetic_Dist ($lat1,$lon1, $lat2,$lon2, $KmMi='km')
{
$Km_or_Mi = (strtolower(substr(trim($KmMi),0,1)) == 'k')? 1:1.609344;
// DEFINE EARTH EQUATORIAL RADIUS
// AND FLATTENING FACTOR.
$R = 6378.137;
$flattening = 1 / 298.257;
$f = deg2rad(($lat1 + $lat2) / 2);
$g = deg2rad(($lat1 - $lat2) / 2);
$h = deg2rad(($lon1 - $lon2) / 2);
$sf = sin($f); $cf = cos($f);
$sg = sin($g); $cg = cos($g);
$sh = sin($h); $ch = cos($h);
$w1 = ($sg * $ch)*($sg * $ch);
$w2 = ($cf * $sh)*($cf * $sh);
$s = $w1 + $w2;
$w1 = ($cg * $ch)*($cg * $ch);
$w2 = ($sf * $sh)*($sf * $sh);
$c = $w1 + $w2;
$o = atan(sqrt($s/$c));
$r = sqrt($s*$c) / $o;
$d = 2 * $R * $o;
$h1 = (3*$r-1) / (2*$c);
$h2 = (3*$r+1) / (2*$s);
$w1 = ($sf * $cg) * ($sf * $cg) * $h1 * $flattening + 1;
$w2 = ($cf * $sg) * ($cf * $sg) * $h2 * $flattening;
return $d * ($w1 - $w2) * $Km_or_Mi;
}
/*
Convert DMS string to decimal degrees.
Example: Given DMS string = "9 12 50.306"
Returned = 9.2139738888888889
*/
function DMS_to_Deg ($DMSstr)
{
// ----------------------------------------------------------
// Read angle/time string argument and force to lower case in
// the event any (deg d h m s : ° ' ") symbols are used.
$dms = strtolower(trim($DMSstr));
// ------------------------------------------------------
// Convert any (deg d m s ° ' ") symbols into spaces.
$dms = str_replace('deg', ' ', $dms);
$dms = str_replace('d', ' ', $dms);
$dms = str_replace('m', ' ', $dms);
$dms = str_replace('s', ' ', $dms);
$dms = str_replace('°', ' ', $dms);
$dms = str_replace("'", ' ', $dms);
$dms = str_replace('"', ' ', $dms);
$dms = str_replace("°", ' ', $dms);
// ----------------------------------------------------
// Normalize the spacing and then split and extract the
// individual angle/time string elements (dh or hh, mm,ss).
$dms = preg_replace("/\s+/", " ", trim($dms));
$wdms = preg_split("[ ]", $dms);
$wdmsCount = count($wdms);
$dd = ($wdmsCount >= 1)? bcadd($wdms[0],"0", 20) : "0";
$mm = ($wdmsCount >= 2)? bcadd($wdms[1],"0", 20) : "0";
$ss = ($wdmsCount >= 3)? bcadd($wdms[2],"0", 20) : "0";
// ------------------------------------------------
// Remember and then remove any numerical (±) sign.
$NumSign = (substr($DMSstr,0,1) == '-')? '-' : '';
$dd = str_replace('-', '', $dd);
$dd = str_replace('+', '', $dd);
// -------------------------------------------------------------
// If original angle argument began with a + sign, then preserve
// it so that all returned positive results will have a + sign.
// Otherwise, positive results will NOT have a + sign.
if (substr($DMSstr,0,1) == '+') {$NumSign = '+';}
// ----------------------------------------------
// Compute decimal degrees/hours value equivalent
// to the given dhms argument elements.
$w2 = bcadd(bcadd(bcmul($dd,"3600",20),bcmul($mm,"60",20),20),$ss,20);
// -----------------------------------------------------------
// If result equates to zero, then suppress any numerical sign.
if (bccomp($w2, "0", 20) == 0) {$NumSign = '';}
// ---------------------------------------------------------
// Round off result to 16 decimals, recalling original sign.
return $NumSign . bcadd(bcdiv($w2,"3600",20), "0.00000000000000005",16);
} // End of DMS_to_Deg (...)
/*
========================================================================
Convert decimal degrees to degrees, minutes, seconds of arc.
The angular elements are returned in a space-delimited string.
Optional symbols are attached to the angle elements. The seconds can
optionally be rounded to up to 3 decimals with 0=Default.
Symbols mode = TRUE|FALSE or d|D
TRUE|d|D means to apply DMS symbols to returned string.
FALSE means no DMS symbols are applied to returned string.
========================================================================
*/
function Deg_to_DMS ($AngDeg, $ssDecimals=0, $PosSignSymbol='', $SymbolsMode='d')
{
// Init
$_d_ = $_m_ = $_s_ = '';
// ------------------------------------------------------
// Compute signed angular elements from decimal argument.
// This value is taken as decimal degrees.
$sign = ($AngDeg < 0)? '-' : '';
if (($PosSignSymbol === TRUE or $PosSignSymbol == '+') and $sign == '') {$sign = '+';}
$degrees = abs($AngDeg);
$dd = floor($degrees);
$minutes = 60*($degrees - $dd);
$mm = floor($minutes);
$seconds = 60*($minutes - $mm);
$ss = sprintf("%1.3f", $seconds);
// ----------------------------------
// Check for that blasted 60s glitch.
if ($ss == 60) {$ss = 0; $mm++;}
if ($mm == 60) {$mm = 0; $dd++;}
// ----------------------------
// Format the angular elements.
$dd = sprintf("%02d", $dd);
$mm = sprintf("%02d", $mm);
$ss = sprintf("%1.$ssDecimals" . "f", $ss);
if ($ss < 10) {$ss = "0$ss";}
// Attach optional DMS symbols.
// Default = TRUE (deprecated). Can also use newer 'd' as DMS symbols flag.
if ($SymbolsMode === TRUE or substr(strtolower($SymbolsMode),0,1) == 'd')
{
$_d_ = "°";
$_m_ = "'";
$_s_ = '"';
}
// Done.
return "$sign$dd$_d_ $mm$_m_ $ss$_s_";
} // End of Deg_to_DMS (...)
function Strip_WSpace ($TextString)
{
return preg_replace("/\s+/", " ", trim($TextString));
}
/*
========================================================================
Generates a string of any number of random digits in any given base
from 2 to 36.
All letters (A to Z) used as digits will be returned in uppercase.
ERRORS:
On error, FALSE is returned for invalid argument(s).
========================================================================
*/
function Rand_Digits_Base_B ($NumDigits=1, $BaseB=10, $LZeroSuppressed=FALSE)
{
// Read arguments.
$N = intval($NumDigits);
$B = intval($BaseB);
// Check for invalid argument(s).
if ($B < 2 or $B > 36 or $N < 1) {return FALSE;}
// Define digits spectrum for the given base.
$DigitsSpectrum = substr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",0,$B);
// Construct an N-digit random sequence in base B, one digit at
// a time, using a random 50/50 digit alternation method. There
// will be at least one random base B digit returned.
$RandomDigits = "";
for ($i=0; $i < $N; $i++)
{
if (mt_rand() % 2 == 0)
{$RandomDigits .= substr($DigitsSpectrum, mt_rand(0,$B-1),1);}
else
{$RandomDigits = substr($DigitsSpectrum, mt_rand(0,$B-1),1) . $RandomDigits;}
}
// If LZeroSuppressed flag === TRUE, then leftmost digit of returned
// random digits string must NOT be zero. If it is, then another
// random non-zero digit will be attached to the left of it and
// the rightmost digit dropped. The result will be a normal
// integer value with the required number of digits, but
// never starting with 0 (zero) as the first digit.
if ($LZeroSuppressed === TRUE)
{
$RandomDigits = substr($DigitsSpectrum, mt_rand(1,$B-1),1) . $RandomDigits;
}
return substr("$RandomDigits", 0, $N);
} // End of Rand_Digits_Base_B(...)
function Rand_Decimal($NumDigits=1, $RandSignFlag=FALSE)
{
$RandSign = '';
$NumDigits = floor($NumDigits);
$RandSignFlag = ($RandSignFlag === TRUE)? TRUE:FALSE;
if ($RandSignFlag === TRUE)
{
$RandSign = (mt_rand() % 2 == 0)? '-':'+';
}
return $RandSign.'0.'.Rand_Digits_Base_B($NumDigits);
} // End of Rand_Decimal()
?>