CREATE TABLE `otp` ( `user_email` varchar(255) NOT NULL, `otp_pass` varchar(64) NOT NULL, `otp_timestamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `otp_tries` tinyint(1) NOT NULL DEFAULT '0' ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE `otp` ADD PRIMARY KEY (`user_email`); <?php class OTP { // (A) CONSTRUCTOR - CONNECT TO DATABASE protected $pdo = null; protected $stmt = null; public $error = ""; function __construct() { try { $this->pdo = new PDO( "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] ); } catch (Exception $ex) { die($ex->getMessage()); } } // (B) DESTRUCTOR - CLOSE CONNECTION function __destruct() { if ($this->stmt !== null) { $this->stmt = null; } if ($this->pdo !== null) { $this->pdo = null; } } // (C) GENERATE OTP function generate ($email) { // @TODO - // YOU SHOULD CHECK IF THE PROVIDED EMAIL IS A VALID USER IN YOUR SYSTEM // (C1) CHECK IF USER ALREADY HAS EXISTING OTP REQUEST $this->stmt = $this->pdo->prepare( "SELECT * FROM `otp` WHERE `user_email`=?" ); $this->stmt->execute([$email]); $otp = $this->stmt->fetch(PDO::FETCH_NAMED); // (C2) ALREADY HAS OTP REQUEST if (is_array($otp)) { // @TODO - // ADD YOUR OWN RULES HERE - ALLOW NEW REQUEST IF EXIPRED? // $validTill = strtotime($otp['otp_timestamp']) + (OTP_VALID * 60); // if (strtotime("now") > $validTill) { DELETE OLD REQUEST } // else { ERROR } $this->error = "You already have a pending OTP."; return false; } // (C3) CREATE RANDOM PASSWORD $alphabets = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789"; $count = strlen($alphabets) - 1; $pass = ""; for ($i=0; $i<OTP_LEN; $i++) { $pass .= $alphabets[rand(0, $count)]; } // (C4) DATABASE ENTRY try { $this->stmt = $this->pdo->prepare( "REPLACE INTO `otp` (`user_email`, `otp_pass`) VALUES (?,?)" ); $this->stmt->execute([$email, $pass]); } catch (Exception $ex) { $this->error = $ex->getMessage(); return false; } // (C5) SEND VIA EMAIL // @TODO - FORMAT YOUR OWN "NICE" EMAIL OR SEND VIA SMS. $mailSubject = "Your OTP"; $mailBody = "Your OTP is $pass. Enter it at 3b-challenge.php within 15 minutes."; if (@mail($email, $mailSubject, $mailBody)) { return true; } else { $this->error = "Failed to send OTP email."; return false; } } // (D) CHALLENGE OTP function challenge ($email, $pass) { // (D1) GET THE OTP ENTRY $this->stmt = $this->pdo->prepare( "SELECT * FROM `otp` WHERE `user_email`=?" ); $this->stmt->execute([$email]); $otp = $this->stmt->fetch(PDO::FETCH_NAMED); // (D2) OTP ENTRY NOT FOUND if (!is_array($otp)) { $this->error = "The specified OTP request is not found."; return false; } // (D3) TOO MANY TRIES if ($otp['otp_tries'] >= OTP_TRIES) { $this->error = "Too many tries for OTP."; return false; } // (D4) EXPIRED $validTill = strtotime($otp['otp_timestamp']) + (OTP_VALID * 60); if (strtotime("now") > $validTill) { $this->error = "OTP has expired."; return false; } // (D5) INCORRECT PASSWORD - ADD STRIKE if ($pass != $otp['otp_pass']) { $strikes = $otp['otp_tries'] + 1; $this->stmt = $this->pdo->prepare( "UPDATE `otp` SET `otp_tries`=? WHERE `user_email`=?" ); $this->stmt->execute([$strikes, $email]); // @TODO - TOO MANY STRIKES // LOCK ACCOUNT? REQUIRE MANUAL VERIFICATION? SUSPEND FOR 24 HOURS? // if ($strikes >= OTP_TRIES) { DO SOMETHING } $this->error = "Incorrect OTP."; return false; } // (D6) ALL OK - DELETE OTP $this->stmt = $this->pdo->prepare( "DELETE FROM `otp` WHERE `user_email`=?" ); $this->stmt->execute([$email]); return true; } } // (E) DATABASE SETTINGS - CHANGE TO YOUR OWN! define('DB_HOST', 'localhost'); define('DB_NAME', 'test'); define('DB_CHARSET', 'utf8'); define('DB_USER', 'root'); define('DB_PASSWORD', ''); // (F) ONE-TIME PASSWORD SETTINGS define('OTP_VALID', "15"); // VALID FOR X MINUTES define('OTP_TRIES', "3"); // MAX TRIES define('OTP_LEN', "8"); // PASSWORD LENGTH // (G) NEW OTP OBJECT $_OTP = new OTP(); <!-- (A) OTP REQUEST FORM --> <h1>OTP REQUEST</h1> <form method="post" target="_self"> <input type="email" name="email" required value="[email protected]"/><br> <input type="submit" value="Go"/> </form> <?php // (B) PROCESS OTP REQUEST if (isset($_POST['email'])) { require "2-otp.php"; $pass = $_OTP->generate($_POST['email']); echo $pass ? "<div>OTP SENT.</div>" : "<div>".$_OTP->error."</div>" ; } ?> <!-- (A) OTP CHALLENGE FORM --> <h1>OTP CHALLENGE</h1> <form method="post" target="_self"> <input type="email" name="email" required value="[email protected]"/><br> <input type="text" name="otp" required/><br> <input type="submit" value="Go"/> </form> <?php // (B) PROCESS OTP CHALLENGE if (isset($_POST['email'])) { require "2-otp.php"; $pass = $_OTP->challenge($_POST['email'], $_POST['otp']); echo $pass ? "<div>OTP VERIFIED.</div>" : "<div>".$_OTP->error."</div>" ; } ?>
Write, Run & Share C++ code online using OneCompiler's C++ online compiler for free. It's one of the robust, feature-rich online compilers for C++ language, running on the latest version 17. Getting started with the OneCompiler's C++ compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as C++
and start coding!
OneCompiler's C++ online compiler supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample program which takes name as input and print your name with hello.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Enter name:";
getline (cin, name);
cout << "Hello " << name;
return 0;
}
C++ is a widely used middle-level programming language.
When ever you want to perform a set of operations based on a condition If-Else is used.
if(conditional-expression) {
//code
}
else {
//code
}
You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.
Switch is an alternative to If-Else-If ladder.
switch(conditional-expression){
case value1:
// code
break; // optional
case value2:
// code
break; // optional
......
default:
code to be executed when all the above cases are not matched;
}
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement){
//code
}
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while (condition) {
// code
}
Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.
do {
// code
} while (condition);
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Function gets run only when it is called.
return_type function_name(parameters);
function_name (parameters)
return_type function_name(parameters) {
// code
}