diff --git a/docs/API.md b/docs/API.md
index e0a9624a..f45e2c0e 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -43,8 +43,8 @@ Content live render streaming endpoint.<br>
 ### Request Query Variables
 | key | variables        | description                                                                                                                    |
 |:----|:-----------------|:-------------------------------------------------------------------------------------------------------------------------------|
-| p   | ``1``            | Used for checking the rate limit.                                                                                              |
-| t   | Stream token     | Unique stream identificator which is used for retrieving cached stream info data.                                              |
+| p   | ``1``            | Used for probing the rate limit.                                                                                               |
+| t   | Stream token     | Unique stream ID. Used for retrieving cached stream info data.                                                                 |
 | h   | HMAC             | Hashed combination of: (hashed) ip address, stream token, expiry timestamp, and service name. Used for verification of stream. |
 | e   | Expiry timestamp |                                                                                                                                |
 
diff --git a/package.json b/package.json
index 52745127..cd3dad05 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
     "name": "cobalt",
     "description": "save what you love",
-    "version": "5.3.1",
+    "version": "5.3.2",
     "author": "wukko",
     "exports": "./src/cobalt.js",
     "type": "module",
@@ -30,6 +30,7 @@
         "express-rate-limit": "^6.3.0",
         "ffmpeg-static": "^5.1.0",
         "got": "^12.1.0",
+        "nanoid": "^4.0.2",
         "node-cache": "^5.1.2",
         "url-pattern": "1.0.3",
         "xml-js": "^1.6.11",
diff --git a/src/front/cobalt.css b/src/front/cobalt.css
index 640fe82b..a0760c26 100644
--- a/src/front/cobalt.css
+++ b/src/front/cobalt.css
@@ -147,8 +147,10 @@ button:active,
     background: var(--accent-press);
     cursor: pointer;
 }
+.switch.text-backdrop,
 .switch.text-backdrop:hover,
 .switch.text-backdrop:active,
+.text-to-copy.text-backdrop,
 .text-to-copy.text-backdrop:hover,
 .text-to-copy.text-backdrop:active {
     background: var(--accent);
@@ -648,7 +650,13 @@ input[type="checkbox"] {
     -webkit-user-select: text;
 }
 .expanded .collapse-body {
-    display: block
+    display: block;
+}
+#download-switcher .switches {
+    gap: var(--gap);
+}
+#pd-share {
+    display: none;
 }
 /* adapt the page according to screen size */
 @media screen and (min-width: 2300px) {
diff --git a/src/front/cobalt.js b/src/front/cobalt.js
index a6ac7fb3..1d1d625e 100644
--- a/src/front/cobalt.js
+++ b/src/front/cobalt.js
@@ -91,6 +91,9 @@ function copy(id, data) {
     setTimeout(() => { e.classList.remove("text-backdrop") }, 600);
     data ? navigator.clipboard.writeText(data) : navigator.clipboard.writeText(e.innerText);
 }
+async function share(url) {
+    try { await navigator.share({url: url}) } catch (e) {}
+}
 function detectColorScheme() {
     let theme = "auto";
     let localTheme = sGet("theme");
@@ -174,6 +177,8 @@ function popup(type, action, text) {
             case "download":
                 eid("pd-download").href = text;
                 eid("pd-copy").setAttribute("onClick", `copy('pd-copy', '${text}')`);
+                eid("pd-share").setAttribute("onClick", `share('${text}')`);
+                if (navigator.canShare) eid("pd-share").style.display = "flex";
                 break;
             case "picker":
                 switch (text.type) {
diff --git a/src/localization/languages/en.json b/src/localization/languages/en.json
index 9600ae8d..f6b88990 100644
--- a/src/localization/languages/en.json
+++ b/src/localization/languages/en.json
@@ -52,7 +52,7 @@
         "DownloadPopupWayToSave": "pick a way to save",
         "ClickToCopy": "press to copy",
         "Download": "download",
-        "CopyURL": "copy url",
+        "CopyURL": "copy",
         "AboutTab": "about",
         "ChangelogTab": "changelog",
         "DonationsTab": "donations",
@@ -117,6 +117,7 @@
         "SettingsDubDefault": "original",
         "SettingsDubAuto": "auto",
         "SettingsVimeoPrefer": "vimeo downloads type",
-        "SettingsVimeoPreferDescription": "progressive: direct file link to vimeo's cdn. max quality is 1080p.\ndash: video and audio are merged by {appName} into one file. max quality is 4k.\n\npick \"progressive\" if you want best editor/player/social media compatibility. if progressive download isn't available, dash is used instead."
+        "SettingsVimeoPreferDescription": "progressive: direct file link to vimeo's cdn. max quality is 1080p.\ndash: video and audio are merged by {appName} into one file. max quality is 4k.\n\npick \"progressive\" if you want best editor/player/social media compatibility. if progressive download isn't available, dash is used instead.",
+        "ShareURL": "share"
     }
 }
diff --git a/src/localization/languages/ru.json b/src/localization/languages/ru.json
index abcab52a..3479e755 100644
--- a/src/localization/languages/ru.json
+++ b/src/localization/languages/ru.json
@@ -52,7 +52,7 @@
         "DownloadPopupWayToSave": "выбери, как сохранить",
         "ClickToCopy": "нажми, чтобы скопировать",
         "Download": "скачать",
-        "CopyURL": "скопировать ссылку",
+        "CopyURL": "скопировать",
         "AboutTab": "о {appName}",
         "ChangelogTab": "изменения",
         "DonationsTab": "донаты",
@@ -117,6 +117,7 @@
         "SettingsDubDefault": "оригинал",
         "SettingsDubAuto": "авто",
         "SettingsVimeoPrefer": "тип загрузок с vimeo",
-        "SettingsVimeoPreferDescription": "progressive: прямая ссылка на файл с сервера vimeo. максимальное качество: 1080p.\ndash: {appName} совмещает видео и аудио в один файл. максимальное качество: 4k.\n\nвыбирай \"progressive\", если тебе нужна наилучшая совместимость с плеерами/редакторами/соцсетями. если \"progressive\" файл недоступен, {appName} скачает \"dash\"."
+        "SettingsVimeoPreferDescription": "progressive: прямая ссылка на файл с сервера vimeo. максимальное качество: 1080p.\ndash: {appName} совмещает видео и аудио в один файл. максимальное качество: 4k.\n\nвыбирай \"progressive\", если тебе нужна наилучшая совместимость с плеерами/редакторами/соцсетями. если \"progressive\" файл недоступен, {appName} скачает \"dash\".",
+        "ShareURL": "поделиться"
     }
 }
diff --git a/src/modules/pageRender/page.js b/src/modules/pageRender/page.js
index 25e785b3..2576de41 100644
--- a/src/modules/pageRender/page.js
+++ b/src/modules/pageRender/page.js
@@ -333,7 +333,8 @@ export default function(obj) {
                 name: "download",
                 subtitle: t('DownloadPopupWayToSave'),
                 explanation: `${!isIOS ? t('DownloadPopupDescription') : t('DownloadPopupDescriptionIOS')}`,
-                items: `<a id="pd-download" class="switch full space-right" target="_blank" href="/">${t('Download')}</a>
+                items: `<a id="pd-download" class="switch full" target="_blank" href="/">${t('Download')}</a>
+                <div id="pd-share" class="switch full">${t('ShareURL')}</div>
                 <div id="pd-copy" class="switch full">${t('CopyURL')}</div>`
             })
         })}
diff --git a/src/modules/stream/manage.js b/src/modules/stream/manage.js
index 875a6d98..827af46c 100644
--- a/src/modules/stream/manage.js
+++ b/src/modules/stream/manage.js
@@ -1,4 +1,5 @@
 import NodeCache from "node-cache";
+import { nanoid } from 'nanoid';
 
 import { sha256 } from "../sub/crypto.js";
 import { streamLifespan } from "../config.js";
@@ -11,9 +12,9 @@ streamCache.on("expired", (key) => {
 });
 
 export function createStream(obj) {
-    let streamID = sha256(`${obj.ip},${obj.service},${obj.filename},${obj.audioFormat},${obj.mute}`, salt),
+    let streamID = nanoid(),
         exp = Math.floor(new Date().getTime()) + streamLifespan,
-        ghmac = sha256(`${streamID},${obj.service},${obj.ip},${exp}`, salt);
+        ghmac = sha256(`${streamID},${obj.ip},${obj.service},${exp}`, salt);
 
     if (!streamCache.has(streamID)) {
         streamCache.set(streamID, {
@@ -42,13 +43,15 @@ export function createStream(obj) {
 
 export function verifyStream(ip, id, hmac, exp) {
     try {
-        let streamInfo = streamCache.get(id);
-        if (!streamInfo) return { error: 'this stream token does not exist', status: 400 };
-
-        let ghmac = sha256(`${id},${streamInfo.service},${ip},${exp}`, salt);
-        if (String(hmac) === ghmac && String(exp) === String(streamInfo.exp) && ghmac === String(streamInfo.hmac)
-            && String(ip) === streamInfo.ip && Number(exp) > Math.floor(new Date().getTime())) {
-            return streamInfo;
+        if (id.length === 21) {
+            let streamInfo = streamCache.get(id);
+            if (!streamInfo) return { error: 'this stream token does not exist', status: 400 };
+    
+            let ghmac = sha256(`${id},${ip},${streamInfo.service},${exp}`, salt);
+            if (String(hmac) === ghmac && String(exp) === String(streamInfo.exp) && ghmac === String(streamInfo.hmac)
+                && String(ip) === streamInfo.ip && Number(exp) > Math.floor(new Date().getTime())) {
+                return streamInfo;
+            }
         }
         return { error: 'Unauthorized', status: 401 };
     } catch (e) {