31 Mart 2022

Online Base64 Encoder





24 Mart 2022

SignedString Sınıfı

 Dışarıya açık dosya paylaşmada URL i zaman bazlı kısıtlamak için oluşturulmuş kod parçaları.

EncryptTool.cs

using System;

using System.Security.Cryptography;

using System.Text;


namespace SampleSigner

{

    public static class EncryptTool 

    {

        public static byte[] EncryptSha5126(string plainText)

        {

            if (string.IsNullOrEmpty(plainText))

            {

                throw new ArgumentNullException(nameof(plainText));


            }

            using (var sha = SHA512.Create())

                return sha.ComputeHash(Encoding.UTF8.GetBytes(plainText));

        }


        /// <summary>

        /// 

        /// </summary>

        /// <param name="plainText"> Not Null</param>

        /// <param name="key">byte[64] random bytes</param>

        /// <returns></returns>

        public static byte[] HmacSha256(string plainText, byte[] key)

        {

            if (key == null)

                throw new ArgumentNullException(nameof(key));

            if (key.Length != 64)

                throw new ArgumentException("key.length must be 64");

            if (string.IsNullOrEmpty(plainText))

                throw new ArgumentNullException(nameof(plainText));


            using (HMACSHA256 hmac = new HMACSHA256(key))

            {

                return hmac.ComputeHash(Encoding.UTF8.GetBytes(plainText));

            }

        } 

    }

}



// SignedStringSettings.cs

using System;

namespace SampleSigner
{
    public class SignedStringSettings
    {
        /// <summary>
        /// Key olarak proje her başlatıldığında key değişsin diye dinamik guid üretilmiştir.
        /// İsteyen gömülü key kullanabilir. 
        /// Ben dosya paylaşım süresini uzun tutmayacağım için Guid benim için sorun değil
        /// </summary>
        private SignedStringSettings()
            :this(Guid.NewGuid().ToString())
        {

        }
        private SignedStringSettings(string key)
        {
            var bytes = EncryptTool.EncryptSha5126(key);
            byte[] data = new byte[64];
            Array.Copy(bytes, 0, data, 0, 64);
            Key = data;
        }

        public static readonly Lazy<SignedStringSettings> _instance
            = new Lazy<SignedStringSettings>(() => new SignedStringSettings());

        public static SignedStringSettings Instance => _instance.Value;

        public byte[] Key { get; private set; }

    }
}


// SignedString.cs

using System;
using System.Security.Cryptography;
using System.Text;

namespace SampleSigner
{
    public class SignedString
    {
        private string _text { get; set; }
        private long _validUntil { get; set; }

        private SignedString(string text, DateTimeOffset validUntil)
        {
            _validUntil = validUntil.ToUnixTimeSeconds();
            _text = Sign(text, _validUntil);
        }

        private SignedString(string text)
        {
            _text = text;
        }



        public static SignedString CreateNew(string text, DateTimeOffset to)
        {
            return new SignedString(text, to);
        }
        public static SignedString CreateNew(string text, TimeSpan time)
        {
            return new SignedString(text, DateTimeOffset.UtcNow.Add(time));
        }

        public static SignedString Load(string text)
        {
            return new SignedString(text);
        }



        private string Sign(string text, long validUntil)
        {
            var plainText = Convert.ToBase64String(Encoding.UTF8.GetBytes(text));
            plainText += $".{validUntil}";
            var computedHash = EncryptTool.HmacSha256(plainText, SignedStringSettings.Instance.Key);
            return $"{plainText}.{Convert.ToBase64String(computedHash)}";
        }

        private bool Verify(string signedText, byte[] key)
        {
            if (string.IsNullOrWhiteSpace(signedText))
                throw new ArgumentNullException(nameof(signedText));

            var parts = signedText.Split('.');

            if (parts.Length != 3
                || string.IsNullOrWhiteSpace(parts[0])
                || string.IsNullOrWhiteSpace(parts[1])
                || string.IsNullOrWhiteSpace(parts[2]))
                throw new ArgumentException("Invalid String");

            
           

            byte[] computedBytes = null;
            using (HMACSHA256 hmac = new HMACSHA256(key))
            {
                var checkText = signedText.Substring(0, signedText.LastIndexOf("."));
                computedBytes = EncryptTool.HmacSha256(checkText, SignedStringSettings.Instance.Key);
            }
            var signBytes = Convert.FromBase64String(parts[2]);

            if (computedBytes == null
                || (computedBytes.Length != signBytes.Length))
                return false;

            for (int i = 0; i < computedBytes.Length; i++)
            {
                if (computedBytes[i] != signBytes[i])
                {
                    return false;
                };
            }
            var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            var until = Convert.ToInt64(parts[1]);

            return now < until;
        }

        public override string ToString()
        {
            return _text;
        }

        public bool IsValid => Verify(_text, SignedStringSettings.Instance.Key);

        public string ToUnsignedString()
        {
            if (IsValid)
            {
                var parts = _text.Split(".");
                var byteText = Convert.FromBase64String(parts[0]);
                return Encoding.UTF8.GetString(byteText);
            }
            else return string.Empty;
        }
    }
}

// Program.cs

using System;
using System.Threading;

namespace SampleSigner
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var plainUrl = "https://www.muharrembarkin.com/";
            var sample = SignedString.CreateNew(plainUrl, TimeSpan.FromSeconds(5));
            // Url is valid 5 seconds
            var signedUrl = sample.ToString();
            Console.WriteLine($"Signed Url: {sample}");

            Console.WriteLine();

            //  1 second later  valid
            Thread.Sleep(1000);
            var sample2 = SignedString.Load(signedUrl);
            Console.WriteLine($"Is Valid after 1 seconds: {sample2.IsValid}");
            Console.WriteLine();
            Console.WriteLine("1 Second later Unsigned Url: " + sample2.ToUnsignedString());
            Console.WriteLine();
            //  6 second later not valid
            Thread.Sleep(5000);
            Console.WriteLine($"Is Valid after 6 seconds: {sample2.IsValid}");
            Console.WriteLine();
            Console.WriteLine("6 Second later Unsigned Url: " + sample2.ToUnsignedString());

            Console.WriteLine();
            var sample3 = SignedString.CreateNew(plainUrl, TimeSpan.FromSeconds(30));
            Console.WriteLine($"Signed Url: {sample3}");
            Console.WriteLine();
            Console.WriteLine("lets change one character of signed url");
            var signedUrl2 = sample3.ToString();
            signedUrl2 = signedUrl2.Substring(0, signedUrl2.Length - 1) + "a";
            Console.WriteLine("Changed Url: " + signedUrl2);
            Console.WriteLine();
            var sample4 = SignedString.Load(signedUrl2);
            Console.WriteLine($"Is valid changed url: {sample4.IsValid}");
            Console.WriteLine();
            Console.WriteLine($"UnsignedString changed url: {sample4.ToUnsignedString()}");
            Console.WriteLine();
            Console.WriteLine("Re test original url");
            var sample5 = SignedString.Load(sample3.ToString());
            Console.WriteLine($"IsValid: {sample5.IsValid}");
            Console.WriteLine($"UnsignedString: {sample5.ToUnsignedString()}");

        }
    }
}

30 Aralık 2021

HTML Loader Vanilla JS

//amagiloader.js 


const AmagiLoader = {

    __loader: null,

    show: function () {


        if (this.__loader == null) {

            var divContainer = document.createElement('div');

            divContainer.style.position = 'absolute';

            divContainer.style.left = '0';

            divContainer.style.top = '0';

            divContainer.style.width = '100vw';

            divContainer.style.height = '100vh';

            divContainer.style.backgroundColor = 'rgba(250, 250, 250, 0.80)';


            var div = document.createElement('div');

            div.style.position = 'absolute';

            div.style.left = '50%';

            div.style.top = '50%';

            div.style.zIndex = '9999';

            div.style.height = '64px';

            div.style.width = '64px';

            div.style.margin = '-76px 0 0 -76px';

            div.style.border = '8px solid #e1e1e1';

            div.style.borderRadius = '50%';

            div.style.borderTop = '8px solid #F36E21';

            div.animate([

                { transform: 'rotate(0deg)' },

                { transform: 'rotate(360deg)' }

              ], {

                duration: 2000,

                iterations: Infinity

              });

            divContainer.appendChild(div);

            this.__loader = divContainer

            document.body.appendChild(this.__loader);

        }

        this.__loader.style.display="";

    },

    hide: function(){

        if(this.__loader!=null)

        {

            this.__loader.style.display="none";

        }

    }

}



Usage //index.html


<html>

<head></head>

<body>

<p>asdsadasd

asdsadasdd

asdasdasd</p>


<script src="amagiloader.js"></script>

<script>

 AmagiLoader.show();

 setTimeout(() => {

    AmagiLoader.hide();

 }, 3000);

</script>


</body>

</html>

22 Kasım 2021

PostgreSQL Sequence Set


ERROR: duplicate key value violates unique constraint "pkey"

DETAIL: Key (id)=(1503) already exists. SQL state: 23505



SELECT MAX(the_primary_key) FROM the_table;   
SELECT nextval('the_primary_key_sequence');


Get Sequence Name

 select pg_get_serial_sequence('tableName','columnName')


Set Sequence Name
SELECT setval('the_primary_key_sequence', (SELECT MAX(the_primary_key) FROM the_table)+1);

VEYA
SELECT setval(pg_get_serial_sequence('tableName','columnName'), (SELECT MAX(columnName) FROM tableName)+1);




5 Kasım 2021

PHP - .NET Uyumlu AES Şifreleme

 C#

using System.Security.Cryptography;

using System.Text;


namespace ConsoleApp16

{

    public class Program

    {

        public static void Main()

        {

            var plain = "Lorem Ipsum";

            var encryptSettings = new EncryptSettings();

            var encryptTools = new EncryptTools(encryptSettings);

            var encrypted = encryptTools.AesEncrypt(plain);

            Console.WriteLine("Encrypted");

            Console.WriteLine(encrypted);

            Console.WriteLine();

            Console.WriteLine("Decrypted");

            var text = encryptTools.AesDecrypt(encrypted);

            Console.WriteLine(text);

        }

    }

    public class EncryptSettings

    {

        public string Key { get; set; }


        public EncryptSettings()

        {

            Key = "passwordstring";

        }

    }


    public class EncryptTools

    {

        private readonly EncryptSettings encryptSettings;


        public EncryptTools(EncryptSettings encryptSettings)

        {

            this.encryptSettings = encryptSettings;

        }


        private byte[] key => Sha256Byte(encryptSettings.Key);

        private byte[] iv => new byte[16] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };


        public string AesEncrypt(string plainText)

        {

            if (plainText == null || plainText.Length <= 0)

                throw new ArgumentNullException("plainText");

            if (key == null || key.Length <= 0)

                throw new ArgumentNullException("Key");

            if (iv == null || iv.Length <= 0)

                throw new ArgumentNullException("IV");

            byte[] encrypted;


            using (var aes = Aes.Create())

            {

                aes.Mode = CipherMode.CBC;

                aes.Key = key;

                aes.IV = iv;


                using (var ms = new MemoryStream())

                {

                    using (ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV))

                    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))

                    using (StreamWriter swEncrypt = new StreamWriter(cs))

                    {

                        swEncrypt.Write(plainText);

                    }

                    encrypted = ms.ToArray();

                }

            }

            return Convert.ToBase64String(encrypted);

        }


        public string AesDecrypt(string encryptedText)

        {

            var cipherText = Convert.FromBase64String(encryptedText);


            if (cipherText == null || cipherText.Length <= 0)

                throw new ArgumentNullException("cipherText");

            if (key == null || key.Length <= 0)

                throw new ArgumentNullException("Key");

            if (iv == null || iv.Length <= 0)

                throw new ArgumentNullException("IV");


            string plaintext = null;


            using (Aes aes = Aes.Create())

            {

                aes.Mode = CipherMode.CBC;

                aes.Key = key;

                aes.IV = iv;


                using (MemoryStream msDecrypt = new MemoryStream(cipherText))

                using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))

                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))

                using (StreamReader srDecrypt = new StreamReader(csDecrypt))

                {

                    plaintext = srDecrypt.ReadToEnd();

                }

            }


            return plaintext;

        }


        public byte[] Sha256Byte(string plainText)

        {

            byte[] bytes = null;

            using (SHA256 sha256Hash = SHA256.Create())

            {

                bytes = sha256Hash.ComputeHash(Encoding.ASCII.GetBytes(plainText));

            }

            return bytes;

        }

    }


}

PHP

<?php

function encrypt_decrypt($string, $action = 'encrypt')
{
$encrypt_method = "aes-256-cbc";
$secret_key = 'passwordstring'; // user define private key
$key = substr(hash('sha256', $secret_key, true), 0, 32);
$iv = chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0);
if ($action == 'encrypt') {
$output = openssl_encrypt($string, $encrypt_method, $key, OPENSSL_RAW_DATA, $iv);
$output = base64_encode($output);
} else if ($action == 'decrypt') {
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, OPENSSL_RAW_DATA, $iv);
}
return $output;
}
echo encrypt_decrypt('CSBx7hQRszpDKM9Vfxy8qQ==', 'decrypt');

?>

14 Ekim 2021

6 Karakterli Unique Key Üretme

 using System;

using System.Collections.Generic;
using System.Text;

namespace ConsoleApp14
{
    class Program
    {
       
        static void Main(string[] args)
        {
            var generatedKeys = new List<string>();
            for (int i = 0; i < 100000; i++)
            {
                var key = KeyGenerator.Generate(i);
                if (generatedKeys.Contains(key))
                    throw new Exception("Tekrar eden numaralar var");
                Console.WriteLine(key);
                generatedKeys.Add(key);
            }
        }
    }

    public static class KeyGenerator
    {
        // chars count must be prime number
        // (mine are 31 i also shuffled them you can re shuffle your letters)
        private static readonly char[] chars = {
                'C', 'V', 'M', 'J', '4', 'E', 'Y','L','R','N','9','5','Z','3','X',
                'D','8','G','T','6','K','W','P','B','S','U','F','H','A','2','7'
            };
        private static int Mod(int a, int b)
           => ((a % b) + b) % b;

        /// <summary>
        /// Generates Unique 6 Character Key By Id
        /// </summary>
        /// <param name="index"> Min 0 Max 887,503,680</param>
        /// <returns></returns>
        public static string Generate(int index)
        {
            // I am calculating 6 digit which means 31^6 = 887503681 possible number
            // I multiplied with 2 different very big prime numbers to prevent similar generated keys
            var number = Mod((index * 8969 * 10457), 887503681);
            var sb = new StringBuilder();
            while (number > 30)
            {
                var letter = chars[(number % 31)];
                sb.Append(letter);
                number = number / 31;
            }
            sb.Append(chars[number]);
            // if it's shorter than 6 character we add last character example (1 =>001)
            while (sb.Length < 6)
            {
                sb.Insert(0, chars[30]);
            }

            return sb.ToString();
        }
    } 
}


SQL User Defined Function

create function [dbo].[udf_GenerateSixCharacterKey] 
(@index int)
returns varchar(6)  as
begin 
declare @a int, 
@b int
set @a = @index * 8969 * 10457
set @b = 887503681

declare @number int
set @number = ((@a % @b) + @b) % @b

declare @chars varchar(31)
set @chars = 'CVMJ4EYLRN95Z3XD8GT6KWPBSUFHA27'

declare @key varchar(6)
set @key = ''

while @number > 30
begin 
set @key = @key + substring(@chars, (@number % 31) + 1, 1)
set @number = @number / 31
end

set @key = @key + substring(@chars, @number + 1, 1)

while len(@key) < 6
begin
set @key = substring(@chars, 31, 1) + @key
end

return @key

end

2 Eylül 2021

AES Encryption Quick Code

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace AesSample
{
    class Program
    {
        static void Main(string[] args)
        {
            //appsettings üzerinden okunduğunu varsayalım.
            var encryptSettings = new EncryptSettings()
            {
                IV = "LoremIpsum",
                Key = "DolorSitAmet",
            };

            IEncryptTools encryptTools = new EncryptTools(encryptSettings);

            var sampleText = "Knowing is not enough; we must apply. Willing is not enough; we must do";

            var encrypted = encryptTools.AesEncrypt(sampleText);

            Console.WriteLine("Encrypted:");
            Console.WriteLine(encrypted);
            Console.WriteLine();

            var decrypted = encryptTools.AesDecrypt(encrypted);
            Console.WriteLine("Decrypted");
            Console.WriteLine(decrypted);

        }
    }

    public interface IEncryptTools
    {
        string AesEncrypt(string plainText);
        string AesDecrypt(string encryptedText);
        byte[] Sha256Byte(string plainText);
        string Sha256String(string plainText);
        string Sha256String(byte[] bytes);
    }

    public class EncryptSettings
    {
        public string Key { get; set; }
        public string IV { get; set; }

    }

    public class EncryptTools : IEncryptTools
    {
        private readonly EncryptSettings encryptSettings;

        public EncryptTools(EncryptSettings encryptSettings)
        {
            this.encryptSettings = encryptSettings;
        }


        private byte[] key => Sha256Byte(encryptSettings.Key);
        private byte[] iv => new List<byte>(Sha256Byte(encryptSettings.IV))
            .GetRange(0, 16).ToArray();
        public string AesEncrypt(string plainText)
        {
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (key == null || key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (iv == null || iv.Length <= 0)
                throw new ArgumentNullException("IV");
            byte[] encrypted;

            using (var aes = Aes.Create())
            {
                aes.Key = key;
                aes.IV = iv;

                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

                using (var ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(cs))
                        {
                            swEncrypt.Write(plainText);
                        }
                        encrypted = ms.ToArray();
                    }
                }
            }
            return Convert.ToBase64String(encrypted);
        }

        public string AesDecrypt(string encryptedText)
        {
            var cipherText = Convert.FromBase64String(encryptedText);

            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (key == null || key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (iv == null || iv.Length <= 0)
                throw new ArgumentNullException("IV");

            string plaintext = null;

            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = key;
                aesAlg.IV = iv;

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }

            return plaintext;
        }

        public byte[] Sha256Byte(string plainText)
        {
            byte[] bytes = null;
            using (SHA256 sha256Hash = SHA256.Create())
            {
                bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(plainText));
            }
            return bytes;
        }

        public string Sha256String(byte[] bytes)
        {
            var builder = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                builder.Append(bytes[i].ToString("x2"));
            }
            return builder.ToString();
        }

        public string Sha256String(string plainText)
        {
            var bytes = Sha256Byte(plainText);
            return Sha256String(bytes);
        }
    }
}
 

23 Ağustos 2021

ASP.NET Core Middleware Response Body Değiştirme

using Sample.Settings;
using Microsoft.AspNetCore.Http;
using System.IO;
using System.Threading.Tasks;

namespace Sample.Middlewares
{
    public class ContentModifyMiddleware
    {
        private readonly RequestDelegate next;
        private readonly MySettings mySettings;
        public ContentModifyMiddleware(RequestDelegate next,
            MySettings mySettings)
        {
            this.next = next;
            this.mySettings = mySettings;
        }

        public async Task Invoke(HttpContext context)
        {
            // Başlangıç: Hangi Koşullarda Değiştireceğim (Opsiyonel)
            var modifyBody = false;
            object controllerName = null;
            modifyBody = (context.Request.RouteValues != null
                && context.Request.RouteValues.TryGetValue("controller", out controllerName)
                && mySettings.ReplaceTexts != null
                && mySettings.ReplaceTexts.Count > 0);
            modifyBody &= (controllerName != null && controllerName.ToString() == "Home");
            // Bitiş: Hangi Koşullarda Değiştireceğim (Opsiyonel)
          
            // Başlangıç: İçerik Değiştirilsin
            if (modifyBody)
            {
                // Orjinal Body Yedekle
                var originalBody = context.Response.Body;
               
                // Değişikliklerin Yapılacağı Yeni Body
                var newBody = new MemoryStream();
                context.Response.Body = newBody;

                // Response'u al
                await next(context);

                // Responsu string olarak oku
                newBody.Position = 0;
                var newContent = await new StreamReader(newBody).ReadToEndAsync();

                // Başlangıç: Response Üzerinde Değişiklikeri Yap
                // (Replace alanlarını appsettings.json dan okuyorum - siz gömülü kod kullanabilirsiniz.)
                foreach (var item in mySettings.ReplaceTexts)
                {
                    newContent = newContent.Replace(item.Old, item.New);
                }
                // Başlangıç: Response Üzerinde Değişiklikeri Bitiş
               
                //String üzerinde yapılan değişiklikler tekrar stream'a dönüştürülüyor. Ve değiştirilmiş stream original body ile değiştiriliyor.
                using (var stream = new MemoryStream())
                {
                    var writer = new StreamWriter(stream);
                    writer.Write(newContent);
                    writer.Flush();
                    stream.Position = 0;
                    await stream.CopyToAsync(originalBody);
                }
                newBody.DisposeAsync();
                context.Response.Body = originalBody;
            }
            // Bitiş: İçerik Değiştirilsin
            // Başlangıç: İçerik Değiştirilmeden Geç
            else
            {
                await next(context);
            }
            // Bitiş: İçerik Değiştirilmeden Geç
        }
    }
}
 

26 Mayıs 2021

MVC JQuery Validate Unobtrusive Boostrap Class

<script src="jquery.js"></script> 

<script src="jquery.validate.js"></script> 

<script src="jquery.validate.min.js"></script> 

 <script>
        var validationSettings = {
            validClass: "is-valid",
            errorClass: "is-invalid"
        };
        $.validator.setDefaults(validationSettings);
        $.validator.unobtrusive.options = validationSettings;
    </script>

22 Nisan 2021

Javascript ile HTML i PDF'e çevirme (html-to-pdfmake, pdfmake)

jsPDF düzgün bir görüntü vermediği için pdfmake ve html-to-pdfmake kullanılmıştır.

Eğer bu kütüphaneleri kullanacaksanız iki kütüphaneye de github üzerinden yıldız vermeyi unutmayın. 

Kullanılan Kütüphaneler

https://pdfmake.github.io/docs/0.1/

https://github.com/Aymkdn/html-to-pdfmake

<!doctype html>
<html lang='en'>
    <head>
        <meta charset='utf-8'>
        <title>my example</title>
        <style>
        /*Hide style for print screen*/
        
            @media print {
            .noPrint {
                display: none;
            }
        }
        </style>
    </head>
    <body>
        <div class="noPrint">
            <button type="button" onclick="downloadPdf()">PDF(HtmlToPdfMaker)</button>
            <!--Print doesn't come with pdf download option on mobile phones, but it has save as pdf option on web browsers in Windows-->
            <button type="button" onclick="window.print()">Print(Vanilla JS)</button>
        </div>
        <div id="pdfContent">
            <h1>Some Html Codes</h1>
        </div>

        <script src='https://cdn.jsdelivr.net/npm/pdfmake@latest/build/pdfmake.min.js'></script>
        <script src='https://cdn.jsdelivr.net/npm/pdfmake@latest/build/vfs_fonts.min.js'></script>
        <script src="https://cdn.jsdelivr.net/npm/html-to-pdfmake/browser.js"></script>
        <script>
            function downloadPdf() {
                var val = new htmlToPdfmake(document.getElementById('pdfContent').innerHTML);
                var dd = { content: val };
                pdfMake.createPdf(dd).download('FileName.pdf');                
            }
        </script>
    </body>
</html>