New Book: A Boat on the Sea of Stories

boat front viewHi guys!

A belated Happy Diwali to all of you.

I am proud and happy to announce my latest endeavor, a book of short stories entitled “A Boat on the Sea of Stories”.

This collection of twelve delectable and highly imaginative tales covers a wide range of themes, ranging from the triumph of an underdog, to a life-changing friendship, to the study of a parasitic man, a sensitive portrayal of an elderly Muslim man, from science fiction mingled with humor or crime, to political intrigue and revenge, from a comedy of errors to Indian mythology retold, from a love of nature to a mystical encounter with a wolf, and finally a saga of rebirth and retribution. The factual science parts in the two science fiction stories are consistent with the latest scientific research.

Each of these original stories has a different flavor and taste. Various characters from different walks of life find themselves in unexpected situations. Together, they remind us that decent, sad, funny, inconsequential life goes on. And, humans do not exist by themselves alone; they are supported by numerous known and unknown living entities.

Each story stands out from the rest and is worth appreciating for itself. All the stories are written in an easy-to-read style. Both Paperback and eBook formats are available on Amazon.in.

Do check it out if you are interested. I shall be obliged if you support my literary efforts. Your feedback as a review is always welcome!

https://amazon.in/dp/9392830971

https://apkpublishers.com/book-store/best-sellers/a-boat-on-the-sea-of-stories/

https://www.amazon.com/Boat-Sea-Stories-Pratyush-Deb-ebook/dp/B0CLL17DGV/

Adding Voice to Captcha to Secure Web Forms

Hi Guys!

In my last post here, I discussed the creation of a captcha code to secure web forms using the HTML 5 Canvas tag along with JavaScript and PHP as the server side language. I loaded a custom web font using the JavaScript Font Face API to draw a random text string on the canvas with it. The random Captcha text was also refreshable in case the site visitor did not find it legible enough.

I assume that the reader knows PHP Web Forms and Sessions, CSS, HTML5 Canvas JavaScript API, JavaScript for browsers including FontFace API, Audio API and AJAX. You may read the appropriate tutorials from the web if you don’t.

So, what’s new in this post? I have used a text to speech API to let users hear audio captcha, in case the captcha is not very legible or the user has a vision problem.

How to create a random string

The following code creates a random text and initializes it into the PHP session.

<?php @session_start(); $_SESSION["captcha_hash_voice"] = substr(hash('joaat', microtime()), 0, 6); ?>

As you can see, a timestamp is created with a call to the microtime() function. It is then hashed with the JOAAT algorithm. We then extract the first six characters of this hash as our captcha string.

Creating The Web Form

We will create the HTML form or web form using HTML and CSS for coding and styling. Here it is:

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style type="text/css">
  #captcha_img{ display:none; }
  #captcha_code{ width: 180px; }
  #captcha{ border: solid 1px black; float:left; }
  #refresh_img{ cursor:pointer; }
  #play_audio{ cursor:pointer; }
  </style>
  <script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script>
</head>
<body>
  <h1>Canvas Captcha with Voice</h1>
  <?php if(isset($_SESSION["form_msg"])){ echo $_SESSION["form_msg"]; unset($_SESSION["form_msg"]); } ?>
  <img src="images/captcha.jpg" alt="captcha image" id="captcha_img" />
  <form action="" method="POST">
  <canvas id="captcha" width="218" height="60" ></canvas>
  <span >&nbsp;<img src="images/refresh.png" alt="refresh image" id="refresh_img" title="Refresh" /><br/>
  &nbsp;<img src="images/audio.png" alt="play_audio" id="play_audio" title="Play audio" /></span>
  <br /><br />
  <input type="text" name="captcha_code" value="" id="captcha_code" maxlength="6" />
  <input type="submit" name="submit" value="Submit" />
  </form>
  <script src="script/js/script.js"></script>
</body>
</html>

As you can see, we declare an HTML 5 document with the DOCTYPE declaration. We fetch the latest jQuery file from https://code.jquery.com/ in the script tag in the head of the HTML 5 document we just created.

We have created an invisible image fetching the image from the path “images/captcha.jpg” relative to our document or web page. We have also used some CSS to style the text input of our web form.

Notice the call to fetch “script/js/script.js”. We will discuss this later.

The Script to which Our Form is Submitted

You will notice the script above the <form> tag. In this script, we will simply compare the value of the “captcha_code” form field (i.e. $_POST[“captcha_code”]) and the random string stored in the PHP session (i.e. $_SESSION[“captcha_hash_voice”]) when the form is submitted by the user.

The code is given below:

<?php 
@session_start();

if(isset($_POST["submit"]) && $_POST["submit"] == "Submit")
{
  
  if($_POST["captcha_code"] != $_SESSION["captcha_hash_voice"])
  {
    //failed
    $_SESSION["form_msg"] = "<span style='color:red;'>Security challenge failed!</span>";
    
    header("Location: index.php");
    exit;
  }
  else{
    //passed
    $_SESSION["form_msg"] = "<span style='color:green;'>Security challenge passed!</span>";
    
    header("Location: index.php");
    exit;
  }
}
else{
  $_SESSION["captcha_hash_voice"] = substr(hash('joaat', microtime()), 0, 6);
}

?>

 

The Script That Renders the Captcha String on the Canvas

Perhaps you noticed the call to fetch “script/js/script.js”. Why do we need to do this?

This is needed because we have to reference the PHP session variable $_SESSION[“captcha_hash_voice”], so that we can render it on the HTML 5 canvas using JavaScript.

When the web page loads for the first time, the following code renders the captcha:

var canvasObj = document.getElementById('captcha');
// we need this to load the font
var myFont = new FontFace('myFont', 'url(font/Moms_typewriter.ttf)');

myFont.load().then(function(font){

  // with canvas, if this is ommited won't work
    document.fonts.add(font);

    console.log('Font loaded');

  console.log(canvasObj);
  
  var captchaImage = document.getElementById("captcha_img");

  var context = canvasObj.getContext("2d");
  
  context.drawImage(captchaImage,0,0);
    
  context.font='28px myFont';
  
  var capText = '';
  
  jQuery.get("script/getcaptchastring.php", {'action':'fetch'}, function(response){
    
    capText = response;
    
    var capArray = capText.split('');
  
    drawLines(context);
    
    rotateText(context, capArray);
    
    
  });
  
});

As you can see, there are two JavaScript functions named “drawLines” and “rotateText”, which need elaboration.

The “drawLines” function draws zigzag lines in the captcha image background by obtaining a 2D graphics context of the canvas object using the line of JavaScript as follows:

var context = canvasObj.getContext("2d");

This complete JavaScript function is as follows:

function drawLines(context)
{
  //random lines
  context.moveTo(0,0);
  context.lineTo(80, 60);
  context.stroke();
    
  context.moveTo(50,0);
  context.lineTo(20, 60);
  context.stroke();
    
  context.moveTo(58, 60);
  context.lineTo(100, 0);
  context.stroke();
    
  context.moveTo(110, 0);
  context.lineTo(140, 60);
  context.stroke();
    
  context.moveTo(120, 60);
  context.lineTo(190, 0);
  context.stroke();
}

The “rotateText” function renders the six characters of the split string, which was previously set in PHP session. It rotates the canvas 2D graphical context this way and that, sumultaneously rendering the individual characters of the captcha in the custom font. After finishing its job, the context is restored to its initial orientation.

function rotateText(context, capArray)
{
  //rotated captcha
  
  context.rotate(10 * Math.PI / 180);
  context.fillText(capArray[0], 35, 40);
  
  context.rotate(5 * Math.PI / 180);
  context.fillText(capArray[1], 59, 35);
  
  context.rotate(-5 * Math.PI / 180);
  context.fillText(capArray[2], 79, 30);
  
  context.rotate(-10 * Math.PI / 180);
  context.fillText(capArray[3], 99, 30);
  
  context.rotate(10 * Math.PI / 180);
  context.fillText(capArray[4], 119, 30);
  
  context.rotate(-5 * Math.PI / 180);
  context.fillText(capArray[5], 134, 25);
  
  context.rotate(-5 * Math.PI / 180);
  context.restore();
}

Creating a Refreshable Captcha

In the code listing that creates our web form, notice the following line:

<img src="images/refresh.png" alt="refresh image" id="refresh_img" />

We will add a click handler to it so that captcha can be refreshed on click. We will use AJAX so as to get the PHP session variable from the server side, modify it and render it without reloading the entire page. Refreshing will change the session variable and hence the captcha string, but the logic to render the changed string remains the same.

Note that on each refresh, we need to clear the Canvas of the zigzag lines and the wavy text, so that there is no overwriting and spoiling the appearance of the captcha.

Here is the code:

//Client side code

jQuery(document).ready(function()
{	
  var canvasObj = document.getElementById('captcha');
  
  var captchaImage = document.getElementById("captcha_img");
  
  var context = canvasObj.getContext("2d");
  
  jQuery("#refresh_img").click(function(){
    jQuery.get("script/getcaptchastring.php", {'action':'refresh'}, function(response){
      
      var capArray = response.split('');
      
      context.clearRect(0, 0, canvasObj.width, canvasObj.height);
      
      context.drawImage(captchaImage,0,0);
      
      context.font='28px myFont';
      
      drawLines(context);
      
      rotateText(context, capArray);	
      
    });
  });
});

There is an AJAX call to “script/getcaptchastring.php” which modifies the captcha string. The following is the code listing for getcaptchastring.php:

<?php 
  //server side code

  @session_start();

  if(isset($_GET['action']))
  {
    if($_GET['action'] == 'fetch') //render captcha first time
    {
      echo $_SESSION["captcha_hash_voice"];

      exit();
    }
    elseif($_GET['action'] == 'refresh') //refresh captcha on clicking refresh icon
    {
      $captcha_hash_new = substr(hash('joaat', microtime()), 0, 6);

      $_SESSION["captcha_hash_voice"] = $captcha_hash_new;

      echo $_SESSION["captcha_hash_voice"];

      exit();
    }
  }

?>

Add Audio Functionality

Now let us add voice functionality.

We will use Google’s Text To Speech API, to feed the captcha string to it and get the speech version as result.

Let us see the client-side code, which is an addition to script/js/script.js:

//audio
jQuery("#play_audio").click(function(){
  
  var audioClip = new Audio("script/playback.php?d="+(new Date()).getMilliseconds());
  
  audioClip.load(); //load the audio clip
  audioClip.play(); //play the audio clip
  
}); 

As you can see, we are creating an object of Audio in JavaScript. We are passing the script at the path “playback.php” to it. We are using a query string while loading playback.php so as to prevent caching while playing the sound clip with it. So that the audio clip changes as the captcha string or, in other words the $_SESSION token changes, on refreshing or reloading, for instance.

The code of playback.php is below:

<?php 
  @session_start();
  header("Content-Type: audio/mpeg");

  $audio_split = str_split($_SESSION["captcha_hash_voice"]); //read letter by letter

  foreach($audio_split as $k=>$voice)
  {

    $voice = rawurlencode(htmlspecialchars($voice));

    $audio = file_get_contents('https://translate.google.com/translate_tts?ie=UTF-8&client=gtx&q='.$voice.'&tl=en-IN');
    echo $audio;
  }

  exit;
?>

The following line:

header("Content-Type: audio/mpeg");

is used to tell the browser to treat the output of playback.php as a sound or audio clip.

We feed the captcha string character by character to the text to speech API at:

‘https://translate.google.com/translate_tts?ie=UTF8&client=gtx&q=’.$voice.’&tl=en-IN’

When the speaker icon in the web form, given above, is clicked, the characters are read by the API ,one by one, so that the user can hear them distinctly. The user can then type in his answer to the captcha challenge. If the captcha is refreshed and the speaker icon is clicked, the new captcha will be read aloud for the user, letter by letter.

Conclusion

So all in all, we did the following:

  • Initialized the first six characters of the hash of microtime() as a session variable in PHP
  • Created a HTML 5 page with a web form and Canvas tag.
  • Created a PHP script to which the form will be submitted, to check the captcha challenge.
  • Created a script to render the Captcha string on the background image, with zigzag lines, with wavy characters using a custom font.
  • Created Server side and client side logic to modify the session variable, return it to the client side and render it to the captcha background each time refresh image is clicked and the canvas is cleared.
  • Created functionality to read aloud the captcha rendered on the screen, on clicking the speaker icon on the web form, before or after clicking the refresh icon.

The code can be downloaded here, and the demo can be found here.

I hope you find it useful, with the addition of voice functionality, since we often need to secure web forms with some kind of captcha and some users may have trouble reading the captcha.

Captcha using HTML 5 Canvas and JavaScript

Hi Guys!

It’s been a while since my last post.

In this post, I shall discuss the creation of a captcha code to secure web forms using the HTML 5 Canvas tag along with JavaScript and PHP as the server side language. I will load a custom web font using the JavaScript Font Face API and draw a random text string on the canvas with it. The random Captcha text will also be refreshable in case the site visitor does not find it legible enough.

I assume that the reader knows PHP Web Forms and Sessions, CSS, HTML5 Canvas JavaScript API, JavaScript for browsers including FontFace API and AJAX. You may read the appropriate tutorials from the web if you don’t.

How to create a random string

The following code creates a random text and initializes it into the PHP session.

<?php 
@session_start();

$_SESSION["captcha_hash"] = substr(hash('joaat', microtime()), 0, 6);

?>

As you can see, a timestamp is created with a call to the microtime() function. It is then hashed with the JOAAT algorithm. We then extract the first six characters of this hash as our captcha string.

Creating The Web Form

We will create the HTML form or web form using HTML and CSS for coding and styling. Here it is:

<!DOCTYPE html>
<html>
<head>
  <style type="text/css">
  #captcha_code{ width: 180px; }
  </style>
  <script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script>
</head>
<body>
  <h1>Canvas Captcha</h1>
  <?php if(isset($_SESSION["form_msg"])){ echo $_SESSION["form_msg"]; unset($_SESSION["form_msg"]); } ?>
  <img src="images/captcha.jpg" alt="captcha image" id="captcha_img" style="display:none;" />
  <form action="" method="POST">
  <canvas id="captcha" style="border: solid 1px black;" width="218" height="60" ></canvas>
  <img src="images/refresh.png" alt="refresh image" id="refresh_img" /><br />
  <input type="text" name="captcha_code" value="" id="captcha_code" maxlength="6" />
  <input type="submit" name="submit" value="Submit" />
  </form>
  <script src="script/js/script.js"></script>
</body>
</html>

As you can see, we declare an HTML 5 document with the DOCTYPE declaration. We fetch the latest jQuery file from
https://code.jquery.com/ in the script tag in the head of the HTML 5 document we just created.

We have created an invisible image fetching the image from the path “images/captcha.jpg” relative to our document
or web page. We have also used some CSS to style the text input of our web form.

Notice the call to fetch “script/js/script.js”. We will discuss this later.

The Script to which Our Form is Submitted

You will notice the script above the <form> web form tag above.
In this script, we will simply compare the value of the “captcha_code” form field (i.e. $_POST[“captcha_code”]) and the
random string stored in the PHP session (i.e. $_SESSION[“captcha_hash”]) when the form is submitted by the user.

The code is given below:

<?php 
  @session_start();

  if(isset($_POST["submit"]) && $_POST["submit"] == "Submit")
  {
    
    if($_POST["captcha_code"] != $_SESSION["captcha_hash"])
    {
      //failed
      $_SESSION["form_msg"] = "<span style='color:red;'>Security challenge failed!</span>";
      
      header("Location: index.php");
      exit;
    }
    else{
      //passed
      $_SESSION["form_msg"] = "<span style='color:green;'>Security challenge passed!</span>";
      
      header("Location: index.php");
      exit;
    }
  }
  else{
    $_SESSION["captcha_hash"] = substr(hash('joaat', microtime()), 0, 6);
  }

?>

The Script Which Renders the Captcha String

Perhaps you noticed the call to fetch “script/js/script.js”.

Why do we need to do this?

This is needed because we have to reference the PHP session variable $_SESSION[“captcha_hash”], so that we can render it on the HTML 5 canvas using JavaScript.

When the web page loads for the first time, the following code renders the captcha:

var canvasObj = document.getElementById('captcha');
// we need this to load the font
var myFont = new FontFace('myFont', 'url(font/Moms_typewriter.ttf)');

myFont.load().then(function(font){

  // with canvas, if this is ommited won't work
  document.fonts.add(font);

  console.log('Font loaded');

  console.log(canvasObj);
      
  var captchaImage = document.getElementById("captcha_img");
  
  var context = canvasObj.getContext("2d");
      
  context.drawImage(captchaImage,0,0);
        
  context.font='28px myFont';
      
  var capText = '';
      
  jQuery.get("script/getcaptchastring.php", {'action':'fetch'}, function(response){
        
    capText = response;
        
    var capArray = capText.split('');
      
    drawLines(context);
        
    rotateText(context, capArray);
        
        
  });
      
});

 

As you can see, there are two JavaScript functions named “drawLines” and “rotateText”, which need elaboration.

The “drawLines” function draws zigzag lines in the captcha image background by obtaining a 2D graphics context of the canvas object using the line of JavaScript as follows:

var context = canvasObj.getContext("2d");

This complete JavaScript function is as follows:

function drawLines(context)
{
  //random lines
  context.moveTo(0,0);
  context.lineTo(80, 60);
  context.stroke();
  
  context.moveTo(50,0);
  context.lineTo(20, 60);
  context.stroke();
  
  context.moveTo(58, 60);
  context.lineTo(100, 0);
  context.stroke();
  
  context.moveTo(110, 0);
  context.lineTo(140, 60);
  context.stroke();
  
  context.moveTo(120, 60);
  context.lineTo(190, 0);
  context.stroke();
}

The “rotateText” function renders the six characters of the split string, which was previously set in PHP session. It rotates the canvas 2D graphical context this way and that, sumultaneously rendering the individual characters of the captcha in the custom font. After finishing its job, the context is restored to its initial orientation.

function rotateText(context, capArray)
  {
    //rotated captcha
    
    context.rotate(10 * Math.PI / 180);
    context.fillText(capArray[0], 35, 40);
    
    context.rotate(5 * Math.PI / 180);
    context.fillText(capArray[1], 59, 35);
    
    context.rotate(-5 * Math.PI / 180);
    context.fillText(capArray[2], 79, 30);
    
    context.rotate(-10 * Math.PI / 180);
    context.fillText(capArray[3], 99, 30);
    
    context.rotate(10 * Math.PI / 180);
    context.fillText(capArray[4], 119, 30);
    
    context.rotate(-5 * Math.PI / 180);
    context.fillText(capArray[5], 134, 25);
    
    context.rotate(-5 * Math.PI / 180);
    context.restore();
  } 

Creating a Refreshable Captcha

In the code listing that creates our web form, notice the following line:

<img src="images/refresh.png" alt="refresh image" id="refresh_img" />

We will add a click handler to it so that captcha can be refreshed on click. We will use AJAX so as to get the PHP session variable from the server side, modify it and render it without reloading the entire page. Refreshing will change the session variable and hence the captcha string, but the logic to render the changed string remains the same.

Note that on each refresh, we need to clear the Canvas of the zigzag lines and the wavy text, so that there is no overwriting and spoiling the appearance of the captcha.

Here is the code:

//Client side code

  jQuery(document).ready(function()
  {	
    var canvasObj = document.getElementById('captcha'); //canvas object
    
    var captchaImage = document.getElementById("captcha_img"); //background image
    
    var context = canvasObj.getContext("2d");
    
    //click event handler
    jQuery("#refresh_img").click(function(){
    
      //AJAX GET call
      jQuery.get("script/getcaptchastring.php", {'action':'refresh'}, function(response){
        
        var capArray = response.split('');
        
        context.clearRect(0, 0, canvasObj.width, canvasObj.height); //wipe the canvas clean on each refresh 
        
        context.drawImage(captchaImage,0,0);
        
        context.font='28px myFont';
        
        drawLines(context);
        
        rotateText(context, capArray);	
        
      });
    });
  });

There is an AJAX call to “script/getcaptchastring.php” which modifies the captcha string. The following is the code listing for getcaptchastring.php:

<?php 
@session_start();

if(isset($_GET['action']))
{
  if($_GET['action'] == 'fetch')
  {
    echo $_SESSION["captcha_hash"];

    exit();
  }
  elseif($_GET['action'] == 'refresh')
  {
    $captcha_hash_new = substr(hash('joaat', microtime()), 0, 6);

    $_SESSION["captcha_hash"] = $captcha_hash_new;

    echo $_SESSION["captcha_hash"];

    exit();
  }
}

?>

Conclusion

So all in all, we did the following:

  • Initialized the first six characters of the hash of microtime() as a session variable in PHP
  • Created a HTML 5 page with a web form and Canvas tag.
  • Created a PHP script to which the form will be submitted, to check the captcha challenge.
  • Created a script to render the Captcha string on the background image, with zigzag lines, with wavy characters using a custom font.
  • Created Server side and client side logic to modify the session variable, return it to the client side and render it to the captcha background each time refresh image is clicked and the canvas is cleared.

I hope you found it useful, since we often need to secure web forms with some kind of captcha. The code is found here. The demo is here.

 

Away From Home – eBook

Hi guys!

My latest eBook, entitled “Away From Home:  Two Stories”, features two original short stories that are about love, including filial love, death and closure. The main characters in both the stories find love away from home. The stories might tug at the reader’s heartstrings, but they are really intended to convey that ordinary persons can experience extraordinary feelings in the course of their respective journeys through the river of life and its numerous tributaries. The stories in the eBook are briefly described below.

An Ordinary Love Story:

Shankar, an Indian man, meets a Buddhist Chinese woman online and falls deeply in love with her. He travels all the way to Hong Kong to meet her in person after a virulent epidemic breaks out there. They meet each other. Eventually, the epidemic claims both of them.

Death of a Daughter:

Eklata, an attractive young lawyer, shifts base from Kolkata to Mumbai to work as an intellectual property consultant to a film production company. There, she meets a policeman who falls in love with her. Then, she is brutally murdered by a psychotic character. Her shell-shocked father meets her in a dream. After detailed investigations, aided by the victim’s policeman friend, the Mumbai police is finally successful in bringing the murderer to justice.

It is said that good love stories frequently end in tragedies. Do check out the eBook on amazon.in if you are interested.

Please spread the word if you like it! The link to the eBook is given below.

https://amzn.to/3ScqUEi

My Recent Paperback Of Short Stories

I recently published a paperback, entitled “Thereepooty And Other Stories” on Amazon. It is an anthology of seventeen short stories of different genres and moods. The different characters in these stories find themselves in different situations.

The different genres you will find in this book are science fiction, love and romance, horror, supernatural, humor, animal tales, etc. The stories are for readers of all ages.

To purchase the paperback, go to amazon.com or the amazon site relevant to your country. Choose “Books” in the search bar and then search for “thereepooty” over there. If all goes well, you will see a listing for my paperback in the search results.

Or, alternatively go to https://www.amazon.com/dp/B09YR6BYGK.

Users from countries other than the US can replace “amazon.com” with the amazon site relevant to their own country such as “amazon.co.uk” for the United Kingdom in the above URL.

Hope you enjoy reading it.

Four Ways To Detect Browser Adblockers Using Javascript

Image credit: getadblock.com

Hi guys!

In this post, I will discuss four ways to detect adblockers in browsers using Javascript with jQuery framework. I shall stick to adblocking browser extensions only. This application of code enables you to notify the user of your site whether an adblocking extension is active in the user’s browser or not. The use cases are based on Google Chrome browser and AdBlock browser extension.

1. Offering a DIV as bait to the adblocker

First we create a wrapper DIV. Inside this div we create another DIV having no content and add some CSS classes to the inner DIV such as “adBanner”, “adsBanner”, etc.

We then browse to our webpage with the DIVS in it and with “AdBlock” adblocker extension installed and active in the browser. On opening the Developer tools in the browser, we will see that the inner DIV with the aforementioned CSS classes does not show at all. What happened? The adblocker blocked the element! Now, how do we detect this programmatically?

Simple. We detect the height of the inner DIV with the CSS classes on it. It will be returned as ‘0’ (zero). This can be done with only Javascript or even with jQuery. What action do we take on getting the inner DIV height as 0? We can notify the site visitor that their adblocker is on with say, a popup. We can also ask them politely to switch it off if we have painstakingly monetized our site with adverts, since all those adverts are blocked now.

When the visitor to our site switches off their adblocker and refreshes the page, the inner DIV will not be blocked. (Hopefully!) So then we can choose not to show the popup again.

First, include jQuery file in your test webpage. Now, let’s have a look at code:

The following code goes into the <body> tag of your webpage:

<style>
.adsBanner{
  background-color: transparent;
  height: 1px;
  width: 1px;
  }
</style>
<script>
jQuery(function(){
  if(jQuery('.wrapper').height() == 0)
  {
    alert("Ad Blocker is active");
  }
  else
  {
    alert("Ad Blocker is NOT active");
  }
});
</script>
<h2>Detect addons AdBlock Div Demo</h2>
<div class="wrapper">
  <div class="adBanner adsBanner"></div>
</div>

You will see an alert with a message saying “Ad Blocker is active” in your Chrome browser on browsing to your web page with AdBlock extension active.

Reference: https://html-online.com/articles/detect-adblock-javascript/

2. Offering a dummy ad script to the ad blocker

We create a javascript file called ads.js and keep in the same folder as our test web page. We then create a boolean variable that will be true. Immmediately after this line of code, we make a call to our dummy ad script ads.js. In the dummy script, we set this variable to false. So, when the ad blocker is active, the variable is true. If not, the variable is false.

This simple technique works for many ad blockers but not for some of them such as Privacy Badger. So, when the boolean variable is true, we can choose to show the notification and not show it when the variable is false.

Let’s have a look at the code:

First, the dummy ad script, ads.js:

//simple ad script
usingAdBlocker = false;

Then, the test web page.  The following code goes in your <body> tag of your page. Be sure to include the jQuery file in your <head> tag of the page.

<script>var usingAdBlocker = true;</script>
<script src="ads.js"></script><!-- dummy ad script-->
<script>
if(usingAdBlocker == true)
{
  alert("Ad Blocker active");
}
else
{
  alert("Ad Blocker NOT active");
}
</script>
<h2>Detect addons AdBlock JS Demo</h2>

If your AdBlock extension is active, you will see an alert with the message “Ad Blocker active”

Reference: https://www.labnol.org/code/19818-detect-adblock-javascript

3. Sideloading a web accessible resource of an adblocking browser extension

The more advanced and more popular adblocker extensions do not follow the element blocking technique. They follow a more advanced method of blocking adverts. To deal with this, we side load a web asccessible resource that is part and parcel of the extension itself. How do we find such a resource?

For this example, I will use the Google Chrome browser and the “AdBlock” extension.

You can find the id of the extension by going to your extension manager in Chrome and clicking on the “Details” link corresponding to your adblocker. Here “gighmmpiobklfepjocnamgkkbiglidom” refers to the extension “id” that is assigned to it.

Browse to the following URL in Chrome:

chrome-extension://gighmmpiobklfepjocnamgkkbiglidom/manifest.json

You will see a large JSON object with one key in the array that is “web_accessible_resources”. Choose any one of the URIs under this key. We will use the “adblock-onpage-icon.svg” URI for our example.

Browse the following URL:

chrome-extension://gighmmpiobklfepjocnamgkkbiglidom/adblock-onpage-icon.svg

Verify that this URL loads properly.

What will we have to do to use this URL? We will simply load it in a browser request, ajax or fetch, via Javascript/ jQuery and wait to receive the HTTP response. If we get a HTTP response code of 200, we can be sure that the plugin or extension is active, since it is possible to load it. We can then perform functions identical to point number 1 and 2 as above.

The following code goes in your <body> tag of your page. Be sure to include the jQuery file in your <head> tag of the page.

<h2>Detect addons AdBlock Side Load Demo</h2>
<script>
console.log(navigator);
//JSON Object for extension details 
var ExtensionObj = 
    {
      "extensionName": "AdBlock",
      "extensionID": "gighmmpiobklfepjocnamgkkbiglidom",
      "resourceURL": "/adblock-onpage-icon.svg", //icon128.png
      "fileType": "image",
      "protocolPrefix": "chrome-extension://",
      "browser": "Chrome"
    };
    
//fetch extension resource	
function UrlExistsExt(protocolPrefix, extId, resourceURL, fileType, cb)
{
  
  var url = protocolPrefix+extId+resourceURL;
  
  $.ajax({
    url: url,
    dataType: fileType,
    type: 'GET',
    complete: function(xhr){
      
      console.log(xhr.status);
      
      if (typeof cb == 'function')
        cb.apply(this, [xhr.status]);
    }
  })
        
}
    
//Ghostery
var ShowPopupExt = false;

//mai function
function UnblockerExtFunc(ExtensionObj)
{
  var currExt = ExtensionObj;
  
  if(navigator.userAgent.indexOf(currExt.browser) != -1)
  {
  
    console.log("Browser matched.");
  
    UrlExistsExt(currExt.protocolPrefix, currExt.extensionID, currExt.resourceURL, currExt.fileType, function(status){
        
      if(status == 200)
      {
        ShowPopupExt = true;
        alert('Extension Detected'); //show dialog here
        
      }
      else{
         alert('Extension Not Found');
      }                                
    });
  }
}

UnblockerExtFunc(ExtensionObj);

$(document).ajaxStop(function(){
        
  if(ShowPopupExt)
  {
    alert("Show Popup"); //if dialog is to be displayed
  }

});
</script>

If your AdBlock extension is active, you will see an alert with the message “Extension Detected” and another with the message “Show Popup”.

Reference: https://developer.chrome.com/docs/extensions/mv3/manifest/web_accessible_resources/

4. Using the default adblocker behavior towards standard ad script URLs

There is a third class of adblockers that use even more advanced techniques of blocking ads. And, they provide no web accessible resources to latch on to. So what do we do? We utilize the default adblocking behavior of these extensions towards standard URLs of adblocking scripts.

The logic is as follows: We try to load a standard adblocker script URL using javascript or jQuery. If an adblocker is active, a request to such a script URL will be blocked. If it is not active, it will yield an HTTP response code of 200 or “OK”.

So if we get a HTTP status code of 200 from a request to any standard javacript ad script URL, we can be certain that an adblocker is not active and is not blocking the request.

We can then perform functions identical to point number 1, 2 and 3 as above.

The following code goes in your <body> tag of your page. Be sure to include the jQuery file in your <head> tag of the page.

<h2>Detect addons New URLs</h2>
<script> 

var FlaggedURL = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'; //standard ad script

jQuery(function($){
  function callMe(FlaggedURL)
  {
    $.ajax({
    url: FlaggedURL,
    type: 'GET',
    complete: function(xhr){
      
        console.log(xhr.status); //200 for OK
        
        if(xhr.status === 200)
        {
          alert("NO adblocker active");
          
        }
        else if(xhr.status === 0)
        {
          alert("Adblocker active");
        }
      }
    });
  }
  
  console.log('ready');
  
  callMe(FlaggedURL);
});
</script>

You will see an alert with a message saying “Adblocker active” in your Chrome browser on browsing to your web page with AdBlock extension active.

Reference: https://stackoverflow.com/questions/33812704/run-an-ajax-request-on-a-url-blocked-for-detecting-adblocker-ghostery

Conclusion

So, in this article, I have given four ways of detecting adblockers in browsers using javascript/jQuery. You can easily apply these code snippets to make plugins, scripts, etc.

Did you like the article? Let me know in the comments below!

 

 

How to generate combinations from a set of characters

In this post, I shall share a code sample in Java that generates string combinations of characters from a given set of characters over a specified range of lengths of such string combinations. I hope I am not boring you all with this topic,since it’s my third such code sample to this effect. The other two samples can be found here and here.

Note that this is my fastest such code yet. It maxes out the cores of a multi-core CPU on execution. Also note that I have no systematic algorithm for this one! Does that sound weird?

There is no exponentiation involved in this sample as in the one here. We simply map elements in an integer array to characters in a character array and then convert that character array to a string when we want to do something with it.

We manipulate indices in the integer array by incrementation and decrementation, that’s it. The code uses the concurrency APIs of Java and is fully parallelized. It achieved about twenty two million iterations per second during my tests.

Finally, let me say further that I take no responsibility for what is done with this code.

package com.pratyush.stringgenerator2;

import java.util.concurrent.*;

class StringGenerator2 implements Runnable
{
    private static char[] dictionary = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
  
    static Object locker;
  
    static  ExecutorService es;
  
    static int attempts = 0;
  
    private static String getStringFromIndices(int[] indices, char[] str)
    {
    
      for(int z = 0; z < str.length; z++)
      {
          str[z]=dictionary[indices[z]];
      }
    
      return new String(str);
    
    }
  
    private static long getMaxAttempts(int startLen, int stopLen)
    {
        long myMaxAttempts = 0;
    
        for(int c = startLen; c <= stopLen; c++)
        {
            myMaxAttempts += Math.pow(dictionary.length, c); 
        }
    
        return myMaxAttempts;
    }

    public void run()
    {
    
       long start = System.currentTimeMillis();
    
       generate(6, 8); 
    
       long end = System.currentTimeMillis();
    
       double secs = (end - start)/1000;
    
       System.out.println("time = "+secs);
    
       System.out.println("words = "+attempts);
    
       System.out.println("max words = "+ getMaxAttempts(6,8));
    
       double speed = attempts / secs;
    
       System.out.println("speed = "+speed);
    
       synchronized(locker)
       {
        
           es.shutdownNow();
        
           locker.notify();
       }
    
   }
  
   public static void generate(int startLen, int stopLen)
   {
     int LEN = dictionary.length;
    
     attempts = 0;
    
     String strCombo = "";
    
     for(int currLen = startLen; currLen<= stopLen; currLen++)
     {
         char[] str = new char[currLen];
      
         int[] indexes = new int[currLen];
      
         for(int f = 0; f < indexes.length; f++) 
         {
             indexes[f] = 0;
         }
      
         for(int j = 0; j < LEN; j++ )
         {
             indexes[0] = j;
        
             if(currLen == 1)
             {
          
                 strCombo = getStringFromIndices(indexes, str);
          
                 /***generate string here and do whatever you like***/
          
                 attempts++;
             }
             else
             {
                 while(indexes[1]<LEN)
                 {
                     int i = 1;
            
                     for(i = 1; i < currLen; i++)
                     {
                        if(indexes[i] == LEN)
                        {
                            break;
                        }
              
                        if(i == currLen - 1)
                        {
                
                            strCombo = getStringFromIndices(indexes, str);
                                
                            /***generate string here and do whatever you like***/
                                
                             indexes[i]++;
                             attempts++;
                         }
                     }
            
            
                    for(int k = 2;k<currLen;k++)
                    {
                        if(indexes[k] == LEN)
                        {
                            indexes[k-1]++;
                                
                            for(int l = k; l<currLen; l++)
                            {
                                indexes[l] = 0;
                            }
                        }
                    }
                }
          
                for(int m = 1; m < currLen; m++)
                {
                    indexes[m] = 0;
                }
             }
          }
       }
    
    }
  
    public static void main(String[] args)
    {
    
      es = Executors.newSingleThreadExecutor();
    
      locker = new Object();
    
      es.execute(new StringGenerator2());
    
      try{
         synchronized(locker)
         {
            locker.wait();
         }
      }
      catch(InterruptedException ie)
      {
   ie.printStackTrace();
      }
    
   }	
}

 

Code execution after compilation is shown below:

Sample Code Generating String Combinations of Characters

In my post here, I shared an algorithm to generate all possible combinations of a given set of characters for a specified range of lengths. In this post, I shall share a code sample written in Java that implements the algorithm shared before. It does not use any goto keyword and hence does not create sphagetti code.

The code uses the concurrency API of Java and is fully parallelized. It maxes out the CPU cores of a multi-core CPU and achieves a few million iterations per second. The code sample uses a custom utility function ‘power’ for calculating powers of integers. It is made static for more execution speed.
The code is commented in places to help readers understand it.

As with the algorithm, I take no responsibility for what is done with this code.

package stringgenerator;

import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

public class StringGenerator implements Runnable
{
  private static char[] dict = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'};  //allowed characters
  
  private static ExecutorService ex;
  
  private static AtomicLong attempts = new AtomicLong(0); //count the number of combinations generated
  
  private static Object locker = new Object();
  
  private static long maxAttempts = 0; //total possible combinations of characters of specified lengths
  
  private static int maxLen = 0;
  
  private static long getMaxAttempts(int radix, int maxLen)
  {
    maxAttempts = (power(radix, maxLen) - 1)*radix /(radix-1);
    
    return maxAttempts;
  }
  
  //utility function to calculate powers of integers
  private static long power(int base, int exp)
  {
    if(exp < 0)
    {
      return 1/power(base, -exp);
    }
    else if(exp == 0)
    {
      return 1;
    }
    else{
      long pow = 1;
      for(int p = 1; p <= exp; p++)
      {
        pow*=base;
      }
      
      return pow;
    }
  }
  
  //the main work horse of this program, breaking all possible numbers into combinations
  private static void resolveRadix(int len, long num)
  {
    long[] retVal = new long[len];
    
    int pow = 0;
    int i = -1;

    int radix = len;
    
    for(i = 0; power(radix ,i ) <= num; i++ );
    
    for(int j = 0; j < len - i; j++)
    {
      retVal[j] = 0;
    }
    
    for(int k = len - i; k < len; k++)
    {
      long t = power(radix, i - 1);
      if(i > 1)
      {
      
        retVal[k] = (long)((num - (num % t)) / t);
      
      }
      else
      {
        retVal[k] = (num % radix);
      }
      num -= (retVal[k] * t);
      
      i--;
    }
    
    char[] combo = new char[len];
    
    for(int j = 0; j < len; j++)
    {
      combo[j] = dict[(int)retVal[j]];
    }
    
    String str = new String(combo);
    
    final long attemptsVal = attempts.incrementAndGet();
    
    attempts.set(attemptsVal);
  }
  
  private void generate()
  {
    for(int length = 1; length <= maxLen; length++)
    {
      int radix = dict.length;
      
      long max = (long)power(radix, length);

      for(int i=0;i<max;i++)
      {
        resolveRadix(radix, i);
      }
    }
    
  }
  
  public void run()
  {
    generate();
    
    synchronized(locker)
    {
      locker.notify();
    }
      
    ex.shutdownNow();
    
  }
  
  public static void main(String[] args)
  {
    
    ex = Executors.newSingleThreadExecutor();
    
    maxLen = 6;
    
    long atts = getMaxAttempts(dict.length, maxLen);
    
    StringGenerator threads = new StringGenerator();
    
    long start = System.currentTimeMillis();  //execution start time
    
    ex.execute(threads); //execute code parallelly
    
    try{
        
      synchronized(locker)
      {
        locker.wait();
      }
    }
    catch(InterruptedException ie)
    {
      ie.printStackTrace();
    }
    
    long attemptsVal = attempts.get(); //final total number of attempts
    
    long end = System.currentTimeMillis(); //execution end time
    
    double speed = (double)((1000 * attemptsVal)/(end - start)); //rate of generating combos
    
    double seconds = (double)(end - start) / 1000;
    
    System.out.println("per sec = "+speed);
    
    System.out.println("sec = "+seconds);
    
    System.out.println("words = "+attemptsVal);
    
    System.out.println("max words = "+atts);
    
  }
}

Execution after compilation is shown below:

Algorithm Generating String Combinations of Characters

In this post, I shall reveal another algorithm to generate all possible combinations of a given set of characters,of any predetermined range of lengths. For example, if we take a,b,c as possible characters in our combinations, and 1 to 3 as the range of lengths, then we have the following output:

a
b
c
aa
ab
ac
ba
bb
bc
ca
cb
cc
aaa
aab
aac
aba
abb
abc
....
ccc

This algorithm merely generates the combinations as strings of characters. It is upto the user of this algorithm to decide what to do with the generated string. I take no responsibility for what a user might actually do with this algorithm.

It is a non-recursive algorithm and is highly efficient in terms of usage of memory. Being non-recursive, it avoids the pitfall of call stack overflow, even with a large input space.

As with my other algorithm similar to this one here, one needs to implement parallelized code to max out CPUs and achieve a very high number of iterations per second.

The only limitation is that the combinations generated have a large amount of repetition of characters, which is exacerbated when the specified range of lengths is high.

The algorithm is as follows:

1. take length of string from minLen to maxLen, 
   array of characters being considered as dictionary
2. take current length of string as len
3. take radix as length of character dictionary
4. take max as radix to the power of len
5. from num = 0 to num = max - 1, resolve radix len, num
6. resolve radix as follows
   a. take retVal as array
   b. find p = highest power of radix <= num
   c. from j = 0 to len - p - 1, retVal[j] = 0
   d. from k = len - p to len - 1,
      i. t = radix to the power p - 1
      ii. if p > 1, retVal[k] = (num - (num % t)) / t;
          else retVal[k] = (num % radix)
      iii. num -= (retVal[k] * t)
      iv. p--
   e. build string from retVal using 
      str = empty string
      foreach(retVal as r)
          concat (dictionary[r]) with str
   f. do something with str
7. if len = maxLen 
      quit
   else
      increment len by 1 and goto step 2

The cornerstone of this algorithm is the resolve radix subroutine which does the main work in it. It works similar to conversion of decimal numbers to binary numbers. However, the difference is that in each of the bits, instead of just 0 and 1, we can put numbers ranging from 0 to length of the set of possible characters minus one.

In our case, the character set is a,b,c. So the numbers fitting in the bits are 0,1 and 2,with 0 mapping to ‘a’, 1 mapping to ‘b’ and 2 mapping to ‘c’. The total size generated is equal to the current length. So in our example above, there will be three main iterations, with the total bit size of the ‘number’ ranging from 1 to 3.

So the bit combinations range from

0
1
2
00
01
02
10
11
12
20
21
22
000
001
002
….
222

Using our mapping rules above, we get a from 0, b from 1, c from 2, aa from 00, ab from 01, ac from 02, etc.

Let this be a Valentine’s Day gift for everyone!

Can mankind bet its future on long distance space travel?

Long distance space travel is the stuff of science fiction. Cosmonauts strap themselves into cryogenic hyper-sleep pods while androids with artificial intelligence pilot the ship to exoplanets several light years away. The cosmonauts remain in suspended animation until they reach a predetermined point on their route. The exoplanets themselves have been found to be habitable for humans, of course, and the space ships travel at speeds comparable to the speed of light.  Then, one fine day, mankind blasts off into space to embrace its future as a multi-planetary species, leaving a barren and desolate Earth behind. But, can mankind really bet its future on this kind of interplanetary or intergalactic travel?

In reality, modest beginnings have been made with both private enterprises and national governments working towards setting up bases on the moon as well as nearby planets like Mars. Elon Musk’s Space X is one of the notable private enterprises planning to colonize Mars (1). Governments planning to set up bases on the moon are those of USA, Russia and China, as well as governments of some European nations (2). These activities are supposed to be a stepping stone to venturing deeper into outer space.

The feasibility of long distance or intergalactic space travel hinges on a number of factors:

Finding habitable exoplanets

Habitable exoplanets are rocky planets orbiting stars outside our solar system, at a distance suitable to remain at an atmosphere that makes it possible for chemicals like liquid water to exist. The region at this distance around the star is called the habitable zone. (3)

Such chemicals are essential to sustain human life. So far, thousands of exoplanets have been discovered by NASA. The size of the exoplanet can also be measured based on how much it dims the brightness of the star when passing or transiting in front of it from our point of view. (3)

It is now known that exoplanets are fairly common in the universe.  However, they must be at a suitable distance from Earth for mankind’s ability to reach in order to colonize it. The reason is that even if the exoplanet is a hundred light years away, then assuming that our spaceship travels near the speed of light, it will still take a hundred years to get there. Most cosmonauts will not live beyond that time span! As for children to be born in space, that is a huge leap into the unknown, to say the least.

Invention of travel at nearly the speed of light – wormholes, space warps, etc

The nearest earth-like exoplanet, Proxima Centauri b, is 4.25 light years away. A conventional space craft will take hundreds of thousands of years to get there, at a conservative estimate! Four and a quarter years is a far more feasible time frame, which means that our ship needs to travel at a speed really close to that of light.

According to Marc Millis, a former NASA propulsion scientist, it would take a billion billion Joules of energy, a little bit less than all the energy consumed by the entire world in one year, to get a spacecraft carrying 500 people from Earth to Alpha Centauri, the planetary system closest to our solar system, in 75 years! Obviously, we need a very powerful source of energy, something yielding a huge amount of energy per unit weight.  The actual technology required is at least 200 years away according to Dr. Marc. (4)

What about speeds of light or greater? According to Albert Einstein’s theory of Special Relativity, an object travelling at the speed of light or more will have infinite mass because of the equation E = mc2 , where E is the energy of the object, m is the mass and c is the speed of light. This equation talks about the energy-mass equivalence whereby an object will have an increase in mass as a result of its motion. Energy and mass are essentially the same entity and can be converted to one another.

One might say that Einstein said nothing about tachyons which are already travelling at speeds greater than or equal to that of light.  But common sense tells us that human beings and their spacecraft are not tachyons!

There is no feasible technology to enable travel at the speed of light, let alone speeds more than that of light. In the light of recent developments, however, a few exotic ideas are being considered. These are wormholes and space warps. (5) (6).  The idea of photons propelling rockets has also been bandied about.

The proof of principle for faster-than-light (FTL) space warp propulsion was published decades ago in a 1994 paper by physicist Miguel Alcubierre. Conventional advanced propulsion  technologies are limited to speeds below the speed of light. Even speeds slightly less than that of light will take centuries of research to attain.  Using an FTL space warp will drastically reduce the time and distances of interstellar flight, according to astrophysicist Eric Davis, a leader in FTL.

In current FTL theories, it’s not the ship but space that moves! We know that space is flexible. Space has been expanding steadily since the Big Bang. If we distort the space around the ship instead of accelerating the ship itself, a warp drive would not break Einstein’s special relativity rules. The ship itself doesn’t need to go faster than light with respect to the space immediately around it, thus remaining within the ambit of Einstein’s theory of relativity.

In a warp drive, space in front of the vessel is contracted while space behind it is expanded, propelling it forward and eventually bringing the vessel to its destination. In wormholes, the ship (or perhaps an exterior mechanism) would create a tunnel through space-time, with a targeted entrance and exit. The ship would enter the wormhole at sub-light speeds and reappear in a different location many light-years away.

According to Davis, a wormhole entrance is a sphere that contains the mirror image of a whole other universe or remote region within our universe, which is incredibly shrunken and distorted.

How can we create these space-time distortions that will allow vessels to travel faster than light? Several research scientists are currently studying the feasibility of a warp drive (and EMdrive and a number of other modes of faster than light travel).

It’s believed, and certain preliminary experiments seem to confirm, that producing predetermined   amounts of “negative energy” would achieve the desired effect. Negative energy has been produced in a lab via the “Casimir effect”. This phenomenon is based on the idea that vacuum, contrary to its portrayal in classical physics, isn’t empty. According to quantum theory, a region of vacuum is actually full of electromagnetic fluctuations. Distorting these fluctuations can create negative energy.

According to Caltech physicist Sean Carroll “In short, it requires negative energy densities, which can’t be strictly disproven but are probably unrealistic; the total amount of energy is likely to be equivalent to the mass-energy of an astrophysical body; and the gravitational fields produced would likely rip any ship to shreds. My personal estimate of the likelihood we will ever be able to build a ‘warp drive’ is much less than 1%. And the chances it will happen in the next hundred years I would put at less than 0.01%.”

Engineers have yet to come up with a technique to create a traversable wormhole with a targeted entrance and exit or distort space as envisioned in the concept of a warp drive.

Moreover, most scientists think that such forms of space travel simply aren’t viable, thanks to the fundamental physics of our universe. Dr. Alcubierre himself listed a number of concerns, starting  with the vast amounts of exotic matter that would be needed. The warp drive is impossible on this ground alone, in his opinion. “At speeds higher than the speed of light, the front of the warp bubble cannot be reached by any signal from within the ship,” he emphasized. “This does not just mean we can’t turn it off; it is much worse. It means we can’t even turn it on in the first place.”

Obviously, warping space requires a lot of mass and energy, and ensuring that the space where you are located isn’t warped is very difficult to say the least. Indeed, the proposition was mostly just an  experiment when it was first proposed – not something Alcubierre thought was actually viable technology.

Therefore, the concepts of warp drives and wormholes remain in the realm of fiction.

Invention of hyper-sleep

Hyper sleep or cryosleep is a state of suspended animation in which human metabolism slows down to a negligibly low rate. When a human being is brought out of this state, all bodily functions begin to work like normal. What is the current state of research in this field?

In Prometheus, the prequel to Ridley Scott’s 1979 film Alien, long space voyages are accomplished by putting the travelers to sleep in pods for two years, only waking them when they reach their destination. The aging process itself has been interrupted to allow humans to undertake multiple long trips to the stars. When Alien was released, hyper-sleep was pure science fiction, but work in a laboratory in Seattle, Washington seems to have brought hyper-sleep a step closer to reality. (7).

Mark Roth of the Fred Hutchinson Cancer Research Center has been publishing papers documenting his research on, in his words, keeping living creatures alive for increasingly long periods of time since 2001. First, he took fifty zebra-fish embryos and deprived them of oxygen, slowing down their movement and development for twenty-four hours. Then the embryos were exposed to a normal environment and raised as sexually mature adults. More complex creatures will die if deprived of oxygen. Roth undertook a journey of discovery to find out whether it is possible to de-animate mammals and eventually people.

However, Mark Roth’s research was not about de-animating people to help them undertake long voyages to the stars. Mark Roth wanted to use suspended animation to help people out when in trauma, so they could then be transported to the best place for treatment without suffering the problems of delay they would otherwise experience. Roth started looking for a way to reduce the human metabolic rate, against received wisdom. He searched for a chemical that would facilitate the survival of people and species through extreme cold and lack of resources without lasting ill-effects. After many failures, he came across hydrogen sulfide, a gas which is used in chemical warfare despite the fact that the human body produces it, the highest concentration being located in the human brain. In chemical accidents, it’s known that if you breathe too much of it you collapse to the ground, you appear dead, but then if you’re brought out into normal air you can be re-animated without harm, if done quickly enough. Trials on yeast, nematode worms, and non-hibernating mice were successful.  However, the metabolic rate reducing effects of hydrogen sulfide inhalation seem to be inversely related to body size.

For example, the rate of metabolic depression in rats was several times lower than that in mice.
Also, the same study on swine and sheep could not confirm significant reduction in metabolic rate, oxygen uptake, etc (8).  Finally, in human volunteers, inhalation of hydrogen sulfide during exercise decreased oxygen uptake. However, this was referred to as a toxic effect on aerobic capacity rather than a regulatory effect on metabolism. It was doubtful whether the “suspended animation” observed in mice could be transferred to humans in a clinical setting.

Another alternative is cryogenic sleep. Bodies are preserved through the process of vitrification. An antifreeze agent is added, which will replace water in the cells. The tissue is then cooled to -220 Fahrenheit, but instead of crystallizing into ice, the chemicals clump together and become solid, like glass. The new glass form prevents the cells from bursting and, theoretically, holds them in stasis forever. But the problem is that scientists are yet to come up with a way to thaw or rewarm human tissue back to life. So far, only 50 ml of tissue has been brought back to normal conditions. (9).

In some cases, it’s preferable to just cool a system down to slow down all the functions of metabolism and essentially slow down aging. In other words, it’s not the long distance voyages but the journey to nearby planet Mars that is within reach through stasis similar to what some animal species on earth do already. These species include bears and ground squirrels.

Bottom-line is that research in suspended animation and cryogenic sleep have yet to make enough progress to make the possibility of sleeping through space voyages of extended duration a reality.

Increasing the human lifespan

One of the ways for human beings to survive long duration space trips is to somehow lengthen the human lifespan. Currently, the maximum age anyone has lived up to is about 119 years (10).  Assuming that a person can be put into service as a crew member at the age of 18 and can serve till 90 years, we can easily calculate that a crew member can put in 72 years of service. Also, it is not sufficient for a crew member to serve on board the ship. A base has to be set up on reaching the destination planet.  An optimum number of crew members must be maintained in various departments. Different individuals will have aptitude in different areas of expertise, not necessarily the required area of expertise. Therefore, it might be necessary to find a way to lengthen the lifespan of human beings.

Many researchers have been working to answer the question: “Can we live longer but stay younger?” Research on aging has been carried out mostly on nematode worms (11), (12) and mice, which are nowhere nearly as complex as humans. Doubling of lifespans of mice is not that impressive.

Many researchers are now inclined to think the problem is “epigenetic”. In other words, there is a problem of reading the genetic code in cells, like problems in reading a compact disc over time.  Harvard molecular biologist George Church observed that it is possible to make aging cells repair themselves. David Sinclair, a Harvard geneticist, is a champion of the “hormesis” approach or inducing metabolic stress by intense short-duration exercise or intermittent fasting.

Anti-aging research seems to be proceeding along two fronts: dietary supplements and genetic engineering. The supplements are supposed to activate the right proteins in our cells. Genetic engineering, on the other hand, involves adding or otherwise manipulating genes in a population of animals. In mice, this can be done by reorganizing the genome in the embryo and using it to breed a genetically altered variant. Genetically altered mice that are known to create more of a single protein, sirtuin 6, have been known to live longer. However, this is not accepted as an indication of increased longevity. It is merely equalizing the lifespans of male and female mice.
Researchers are now working on dogs having an average lifespan of a decade or more.

There are problems with this work, even though the lifespans of the test subjects are higher. There are surprisingly few biomarkers of increased longevity. How does one know if the test subjects live longer except by waiting for decades to see when they die?  Ideally, we need something like a chemical signature in a blood test that correlates with an individual’s lifespan.

Scientists are optimistic about genetic engineering since they have already managed to make aging embryonic stem cells become young again by reprogramming them. This has doubled the lifespan of mice in the lab. We have yet to see such results in experiments on dogs. Human beings are a long shot.

Feasibility of space travel for extended periods of time, effect on human gene activity.

Scientsists have believed that space travel for extended periods of time can harm the human body and possibly even damage human DNA. The latest report by NASA seems to have broken down the old age thought that long hours of space travel is hazardous to the human body. (13)  New results from the NASA “Twins Study” have shown that there are no major warning signs and little reason to think that humans cannot survive a two-and-a-half-year round-trip journey to Mars. Christopher Mason, Associate Professor at Weill Cornell Medicine said “the body has extraordinary plasticity and adaptation to being in zero gravity, at least for a year”.

But, what is this much hyped “Twins Study” conducted by NASA? As part of the Twins Study, NASA astronaut Scott Kelly spent nearly a year in space while his identical twin, Mark remained as a control subject on Earth. By means of this experiment, NASA wanted to look at the effects of space travel on the human body.

The study was a first of its kind effort to compare the molecular profiles of identical twins, one in outer space and the other on Earth. It seems that spending nearly a year in space, triggered Scott’s immune system response, so that more activity was observed at the cellular level in Scott’s body as compared to Mark’s body. It also changed the activity of some of Scott’s genes.

Craig Kundrot, Director of NASA’s space life and physical sciences division, emphasized that so far, the space agency’s research found nothing that would make a Mars mission impossible.

However, a Mars mission would expose astronauts to higher levels of radiation than what is permissible under the current guidelines. Radiation alone is sufficient to damage a human being’s body at the cellular level. Also, the duration parameter of the Twins Study was one year, less than half of what it would take for a Mars mission. So, once again, current research should be regarded with cautious optimism.

Physiological effects of long period travel in micro-gravity

The pull of gravity tells the human body to maintain muscle tone and bone density. According to NASA studies, micro gravity implies that this signal is no longer there. (14) Therefore, muscles begin to atrophy and so do bones. Muscles atrophy as quickly as 5% a week and bones at the rate of about 1% a month. Muscles used to support the body against gravity, such as those in the calves and spine, can lose as much as 20 % of their mass. Blood is affected too. On Earth, blood pools in the feet, resulting in a pressure of about 200 mm of Hg (mercury). In the absence of gravity, the gradient of blood pressure is absent. Blood pressure equalizes throughout the body. Astronauts look odd in these conditions. Their faces, filled with fluid, puff up and their legs become thin. Higher blood pressure in the head gives an alarm signal which reduces blood volume. The heart atrophies because there is less blood to pump.

This atrophication of the human body doesn’t matter as long as the astronauts are in the spaceship. But, what happens when they land on an exoplanet? They need to be able to help themselves, because no one will be around to help them. So, what is the solution? Exercise is the key. Devices that simulate resistance and gravity on the human body need to be created and used.
One promising device is called the Lower Body Negative Pressure device (LBNP) which simulates gravity by applying negative pressure on the lower body. It uses the suction of an ordinary vacuum cleaner. It reduces much of the loss of cardiovascular function of muscle and some indices of bone loss as well. It also restores the blood pressure gradient and increases blood pressure to the legs. Therefore, we have the means to mitigate the harmful effects of microgravity resulting from travel in outer space to some extent.

Psychological effects of long period travel and isolation

Viewing the Earth from space can be spectacular and can even be a spiritual experience. On the other hand, space travel for extended periods of time, are bound to have psychological implications because of the change in physical and social environment. It is important to understand the psychological and sociological effects of spaceflight before any long distance expeditions to the stars can be undertaken. (15), (16), (17) This is because the success of any space mission depends on the astronauts functioning together as a cohesive team. Any friction or conflict can jeopardize the entire mission because the success of the mission depends on cooperation among the team members. Crew members are likely to be chosen carefully, screening them for psychiatric conditions beforehand and assessing their personalities.

However, it has been found that the human brain works differently in micro gravity, perhaps because of the alteration of blood supply to the brain, thus affecting the efficiency with which oxygen is supplied to the brain. Working for prolonged periods in outer space is like being isolated and confined to a tin can, away from friends and family, away from the familiar daily sensations like the ground under your feet and the smell of fresh grass. Prolonged isolation and confinement are stressors which are persistent and pose a significant mental health hazard.

There is also the problem of cultural and language diversity in space missions conducted jointly by different nations. Differing work culture and management styles are also a factor.

There have been incidents in the past in space missions where space crew members reported hallucinations, both visual and olfactory sensations. When the brains of astronauts are affected, so is their decision-making and other cognitive abilities, which will be dangerous to the integrity  of long distance missions where there is no real-time contact with mission control on the ground.

Needs and supplies for extended spaceflight.

During extended periods of space travel, spaceships will have food and water supplies.
However, there must be a mechanism of replenishing reserves of both food and water. This can only be possible through agriculture because of the impracticality of resupplying interplanetary missions, both in terms of cost and weight of the shipments. A farm in space will help create a sustainable environment by recycling waste water, faeces and by generating oxygen which will continuously purify the air. (18) A space farm can turn a spaceship into an artificial ecosystem having both a hydrological cycle and nutrient recycling.

However there are technical challenges in this kind of agriculture. Plants grown onboard a spaceship experience higher radiation, lower gravity and lower pressure. Directional light compensates for the microgravity somewhat. Higher radiation for one, damages the DNA of plants. It could also reduce their nutritive value.

Food can lose its nutritive value significantly even when it is stored for a year or so. Long missions can severely deplete the nutritive value of food stored for that long. Once the crew lands on their exoplanet, agriculture will be a labor-intensive activity for the first colonists.

The crew will be a fixed number to begin with. However, death and senescence will deplete man power. The number of crew members can only be maintained through periodic replenishment through the birth of children. Obviously, we need to figure out a way of producing children both onboard their ship and on the exoplanet the crew intends to colonize. We need physically and mentally healthy individuals.

Conclusion

Although some research has been done, it is still too early to conclude that we will be able to colonize exoplanets. Many of the areas of research have yet to provide promising results when subjects were changed from lab animals to humans. Some people might argue that it is still too early to take a call; that we have a lot of time. This optimism can accelerate the ecological decline of our world due to reckless behavior of people, thus reducing the time we have in hand. Reaching  the conclusion that we can colonize exoplanets, might make people even more irresponsible.

Some areas of research may hit unsurmountable roadblocks because of the laws of the natural world, the universe itself. We can’t count on our scientists to solve every research problem in the world. Hence, we should treat research findings with cautious optimism and make sure that we are able to live on Earth as long as humanly possible, with space colonization as a backup plan.

References:

1.       https://www.businessinsider.in/This-speculative-SpaceX-timeline-reveals-roughly-when-where-and-how-Elon-Musk-plans-to-colonize-Mars/2022-2023-Land-the-first-Big-Falcon-Spaceship-on-Mars/slideshow/66206786.cms

2.      https://www.theguardian.com/science/2019/jan/21/china-steps-up-bid-to-win-the-lunar-space-race

3.      https://spaceplace.nasa.gov/all-about-exoplanets/en/

4.      https://www.popsci.com/science/article/2011-01/interstellar-travel-wont-be-possible-least-200-years-according-new-calculations

5.      https://www.space.com/21721-warp-drives-wormholes-ftl.html

6.      https://dailygalaxy.com/2018/09/nasa-faster-than-speed-of-light-space-travel-will-warp-bubbles-enable-dreams-of-interstellar-voyages/

7.      https://www.telegraph.co.uk/technology/news/9319883/Prometheus-Alien-and-the-science-of-hypersleep.html

8.      https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4060059/

9.      https://www.inverse.com/article/31267-cryogenic-sleep-hibernation-space-travel

10.    https://en.wikipedia.org/wiki/List_of_the_verified_oldest_people

11.    https://www.fightaging.org/

12.    https://medicalxpress.com/news/2019-02-fountain-youth-pill-youre-mouse.html

13.    https://www.indiatoday.in/science/story/long-term-space-flight-travel-has-no-effect-on-human-health-nasa-1458178-2019-02-17

14.    https://science.nasa.gov/science-news/science-at-nasa/2001/ast02aug_1

15.    https://en.wikipedia.org/wiki/
Psychological_and_sociological_effects_of_spaceflight

16.     https://www.nasa.gov/feature/conquering-the-challenge-of-isolation-in-space-nasa-s-human-research-program-director

17.     https://www.theguardian.com/science/2014/oct/05/hallucinations-isolation-astronauts-mental-health-space-missions

18.     https://en.wikipedia.org/wiki/Space_farming