mirror of
https://github.com/TheAlgorithms/PHP.git
synced 2025-01-17 15:18:13 +01:00
Merge branch 'master' into add/ciphers/xor_cipher
This commit is contained in:
commit
7bcab5722f
34
.github/workflows/ci.yml
vendored
Normal file
34
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
name: PHP Composer
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate
|
||||
|
||||
- name: Cache Composer packages
|
||||
id: composer-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-php-
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.composer-cache.outputs.cache-hit != 'true'
|
||||
run: composer install --prefer-dist --no-progress --no-suggest
|
||||
|
||||
- name: Run PHPUnit
|
||||
run: composer run-script test
|
@ -12,7 +12,7 @@ We are very happy that you would consider contributing! As a contributor, you ag
|
||||
|
||||
- You did your work - no plagiarism allowed
|
||||
- Any plagiarized work will not be merged
|
||||
- Your work will be distributed under [MIT License](License) once your pull request is merged
|
||||
- Your work will be distributed under [MIT License](LICENSE) once your pull request is merged
|
||||
- Your submitted work follows (or mostly follows) the styles and standards already found in this repo
|
||||
|
||||
**New implementations** are welcome! For example, new solutions for an existing problem, different representations for a graph data structure or an algorithm design with different complexity.
|
||||
|
@ -1,4 +1,5 @@
|
||||
## Ciphers
|
||||
* [Caesar Cipher](https://github.com/TheAlgorithms/PHP/blob/master/ciphers/caesarCipher.php)
|
||||
* [Xor Cipher](https://github.com/TheAlgorithms/PHP/blob/master/ciphers/XORCipher.php)
|
||||
|
||||
## Searching
|
||||
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 The Algorithms
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
25
Maths/AbsoluteMax.php
Normal file
25
Maths/AbsoluteMax.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* This function calculates
|
||||
* Absolute max values from
|
||||
* the different numbers
|
||||
* provided
|
||||
*
|
||||
* @param decimal $numbers A variable sized number input
|
||||
* @return decimal $absoluteMax Absolute max value
|
||||
*/
|
||||
function absolute_max(...$numbers)
|
||||
{
|
||||
if (empty($numbers)) {
|
||||
throw new \Exception('Please pass values to find absolute max value');
|
||||
}
|
||||
|
||||
$absoluteMax = $numbers[0];
|
||||
for ($loopIndex = 0; $loopIndex < count($numbers); $loopIndex++) {
|
||||
if ($numbers[$loopIndex] > $absoluteMax) {
|
||||
$absoluteMax = $numbers[$loopIndex];
|
||||
}
|
||||
}
|
||||
|
||||
return $absoluteMax;
|
||||
}
|
25
Maths/AbsoluteMin.php
Normal file
25
Maths/AbsoluteMin.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* This function calculates
|
||||
* Absolute min values from
|
||||
* the different numbers
|
||||
* provided.
|
||||
*
|
||||
* @param decimal $numbers A variable sized number input
|
||||
* @return decimal $absoluteMin Absolute min value
|
||||
*/
|
||||
function absolute_min(...$numbers)
|
||||
{
|
||||
if (empty($numbers)) {
|
||||
throw new \Exception('Please pass values to find absolute min value');
|
||||
}
|
||||
|
||||
$absoluteMin = $numbers[0];
|
||||
for ($loopIndex = 0; $loopIndex < count($numbers); $loopIndex++) {
|
||||
if ($numbers[$loopIndex] < $absoluteMin) {
|
||||
$absoluteMin = $numbers[$loopIndex];
|
||||
}
|
||||
}
|
||||
|
||||
return $absoluteMin;
|
||||
}
|
29
Maths/CheckPrime.php
Normal file
29
Maths/CheckPrime.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* This function check whether
|
||||
* the provided integer is a prime
|
||||
* number or not.
|
||||
*
|
||||
* @param Integer $number An integer input
|
||||
* @return boolean whether the number is prime or not
|
||||
*/
|
||||
function isPrime(int $number)
|
||||
{
|
||||
if ($number === 2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($number % 2 === 0 or $number < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$i = 3;
|
||||
while ($i < sqrt($number)) {
|
||||
if ($number % $i === 0) {
|
||||
return false;
|
||||
}
|
||||
$i += 2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
20
Maths/Factorial.php
Normal file
20
Maths/Factorial.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* This function calculates
|
||||
* and returns the factorial
|
||||
* of provided positive integer
|
||||
* number.
|
||||
*
|
||||
* @param Integer $number Integer input
|
||||
* @return Integer Factorial of the input
|
||||
*/
|
||||
function factorial(int $number)
|
||||
{
|
||||
if ($number < 0) {
|
||||
throw new \Exception("Negative numbers are not allowed for calculating Factorial");
|
||||
}
|
||||
if ($number === 0) {
|
||||
return 1; // Factorial of 0 is 1
|
||||
}
|
||||
return ($number * factorial($number - 1)); // Recursion since x! = x * (x-1)!
|
||||
}
|
14
Maths/PerfectSquare.php
Normal file
14
Maths/PerfectSquare.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* This function check whether
|
||||
* the provided number is a
|
||||
* perfect square or not.
|
||||
*
|
||||
* @param Decimal $number A decimal input
|
||||
* @return boolean whether the number is perfect square or not
|
||||
*/
|
||||
function is_perfect_square($number)
|
||||
{
|
||||
$root = (int) sqrt($number);
|
||||
return (($root * $root) === $number); // If number's square root is an integer then it's a perfect square else not
|
||||
}
|
52
ciphers/caesarCipher.php
Executable file
52
ciphers/caesarCipher.php
Executable file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Encrypt given text using caesar cipher.
|
||||
* @param string text text to be encrypted
|
||||
* @param int shift number of shifts to be applied
|
||||
* @return string new encrypted text
|
||||
*/
|
||||
function encrypt(string $text, int $shift): string
|
||||
{
|
||||
$encryptedText = ''; // Empty string to store encrypted text
|
||||
foreach (str_split($text) as $c) { // Going through each character
|
||||
if (ctype_alpha($c)) {
|
||||
$placeValue = ord($c) - ord(ctype_upper($c) ? 'A' : 'a'); // Getting value of character (i.e. 0-25)
|
||||
$placeValue = ($placeValue + $shift) % 26; // Applying encryption formula
|
||||
$placeValue += ord(ctype_upper($c) ? 'A' : 'a');
|
||||
$newChar = chr($placeValue); // Getting new character from new value (i.e. A-Z)
|
||||
$encryptedText .= $newChar; // Appending encrypted character
|
||||
} else {
|
||||
$encryptedText .= $c; // Appending the original character
|
||||
}
|
||||
}
|
||||
|
||||
return $encryptedText; // Returning encrypted text
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt given text using caesar cipher.
|
||||
* @param string text text to be decrypted
|
||||
* @param int shift number of shifts to be applied
|
||||
* @return string new decrypted text
|
||||
*/
|
||||
function decrypt(string $text, int $shift): string
|
||||
{
|
||||
$decryptedText = ''; // Empty string to store decrypted text
|
||||
foreach (str_split($text) as $c) { // Going through each character
|
||||
if (ctype_alpha($c)) {
|
||||
$placeValue = ord($c) - ord(ctype_upper($c) ? 'A' : 'a'); // Getting value of character (i.e. 0-25)
|
||||
$placeValue = ($placeValue - $shift) % 26; // Applying decryption formula
|
||||
if ($placeValue < 0) { // Handling case where remainder is negative
|
||||
$placeValue += 26;
|
||||
}
|
||||
$placeValue += ord(ctype_upper($c) ? 'A' : 'a');
|
||||
$newChar = chr($placeValue); // Getting new character from new value (i.e. A-Z)
|
||||
$decryptedText .= $newChar; // Appending decrypted character
|
||||
} else {
|
||||
$decryptedText .= $c; // Appending the original character
|
||||
}
|
||||
}
|
||||
|
||||
return $decryptedText; // Returning decrypted text
|
||||
}
|
@ -1,8 +1,14 @@
|
||||
{
|
||||
"name" : "thealgorithms/php",
|
||||
"description": "All Algorithms implemented in PHP",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"phan/phan": "^2.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vendor/bin/phpunit tests"
|
||||
}
|
||||
}
|
||||
|
18
tests/CiphersTest.php
Executable file
18
tests/CiphersTest.php
Executable file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
use function PHPUnit\Framework\assertEquals;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
require_once __DIR__ . '/../ciphers/caesarCipher.php';
|
||||
|
||||
class CiphersTest extends TestCase
|
||||
{
|
||||
public function testCaesarCipher()
|
||||
{
|
||||
assertEquals('Aopz pz h alza.', encrypt('This is a test.', 7));
|
||||
assertEquals('Aopz pz h alza.', encrypt('This is a test.', 7 + 26));
|
||||
assertEquals('This is a test.', decrypt('Aopz pz h alza.', 7));
|
||||
assertEquals('This is a test.', decrypt('Aopz pz h alza.', 7 + 26));
|
||||
}
|
||||
}
|
59
tests/MathTest.php
Normal file
59
tests/MathTest.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
use function PHPUnit\Framework\assertEquals;
|
||||
use function PHPUnit\Framework\assertFalse;
|
||||
use function PHPUnit\Framework\assertTrue;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
require_once __DIR__ . '/../Maths/Factorial.php';
|
||||
require_once __DIR__ . '/../Maths/CheckPrime.php';
|
||||
require_once __DIR__ . '/../Maths/AbsoluteMax.php';
|
||||
require_once __DIR__ . '/../Maths/AbsoluteMin.php';
|
||||
require_once __DIR__ . '/../Maths/PerfectSquare.php';
|
||||
|
||||
class MathTest extends TestCase
|
||||
{
|
||||
public function testFactorial()
|
||||
{
|
||||
assertEquals(1, factorial(1));
|
||||
assertEquals(120, factorial(5));
|
||||
assertEquals(1, factorial(0));
|
||||
$this->expectException(\Exception::class);
|
||||
factorial(-25);
|
||||
}
|
||||
|
||||
public function testIsPrime()
|
||||
{
|
||||
assertTrue(isPrime(73));
|
||||
assertFalse(isPrime(21));
|
||||
assertFalse(isPrime(1));
|
||||
assertTrue(isPrime(997));
|
||||
}
|
||||
|
||||
public function testAbsoluteMax()
|
||||
{
|
||||
assertEquals(50, absolute_max(12, 20, 35, 50, 50, 23));
|
||||
assertEquals(13, absolute_max(13));
|
||||
assertEquals(54, absolute_max(12, 13, 54, 22));
|
||||
$this->expectException(\Exception::class);
|
||||
absolute_max();
|
||||
}
|
||||
|
||||
public function testAbsoluteMin()
|
||||
{
|
||||
assertEquals(12, absolute_min(12, 20, 35, 50, 50, 23));
|
||||
assertEquals(13, absolute_min(13));
|
||||
assertEquals(12, absolute_min(12, 13, 54, 22));
|
||||
$this->expectException(\Exception::class);
|
||||
absolute_min();
|
||||
}
|
||||
|
||||
public function testPerfectSquare()
|
||||
{
|
||||
assertTrue(is_perfect_square(25));
|
||||
assertFalse(is_perfect_square(43));
|
||||
assertFalse(is_perfect_square(2));
|
||||
assertTrue(is_perfect_square(225));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user