Skip to content

Instantly share code, notes, and snippets.

@in4in-dev
Last active August 20, 2026 05:12
Show Gist options
  • Select an option

  • Save in4in-dev/09f32f313f11b2c10778d9e2ffe7e60e to your computer and use it in GitHub Desktop.

Select an option

Save in4in-dev/09f32f313f11b2c10778d9e2ffe7e60e to your computer and use it in GitHub Desktop.
PHP VK audio unmask (decode extras)
<?php
//(js -> php) code. letter by letter
global $n, $i, $id;
$n = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN0PQRSTUVWXYZO123456789+/=";
$id = 12345; //YOUR USER ID
$i = [
'v' => function($e) {
return strrev($e);
},
'r' => function($e, $t){
global $n;
$e = str_split($e);
for ($o = $n . $n, $s = count($e); $s--;){
$i = stripos($o, $e[$s]);
if(~$i){
$e[$s] = substr($o, $i - $t, 1);
}
}
return implode("", $e);
},
's' => function($e, $t) {
$n = strlen($e);
if ($n) {
$i = r($e, $t);
$o = 0;
$e = str_split($e);
for (; ++$o < $n;){
$p = array_splice($e, $i[$n - 1 - $o], 1, $e[$o]);
$e[$o] = $p[0];
}
$e = implode("", $e);
}
return $e;
},
'i' => function($e, $t){
global $i, $id;
$k = $i['s'];
return $k($e, $t ^ $id);
},
];
function o() {
return false;
}
function a($e){
global $n;
if (!$e || strlen($e) % 4 == 1) {
return !1;
}
$s = 0;
for ($o = 0, $a = "";$s < strlen($e);) {
$i = $e[$s++];
$i = strpos($n, $i);
if ($i !== false) {
$t = ($o % 4) ? 64 * $t + $i : $i;
if ($o++ % 4) {
$a .= chr(255 & $t >> (-2 * $o & 6));
}
}
}
return $a;
}
function r($e, $t) {
$n = strlen($e);
$i = [];
if ($n) {
$o = $n;
$t = abs($t);
for (; $o--;){
$t = ($n * ($o + 1) ^ $t + $o) % $n;
$i[$o] = $t;
}
}
return $i;
}
function s($e){
global $i;
if (!o() && strpos($e, "audio_api_unavailable") !== false) {
$t = explode("?extra=", $e);
$t = $t[1];
$t = explode("#", $t);
$n = ("" === $t[1]) ? "" : a($t[1]);
$t = a($t[0]);
if (!is_string($n) || !$t){ return $e;}
$n = $n ? explode(chr(9), $n) : [];
for ($l = count($n); $l--;) {
$r = explode(chr(11), $n[$l]);
$s = array_splice($r, 0, 1, $t);
$s = $s[0];
if (!$i[$s]){ return $e; }
$t = $i[$s](...$r);
}
if ($t && "http" === substr($t, 0, 4)){ return $t;}
}
return $e;
}
//For example
//EASY <><<><><>
//$extra = s("https://m.vk.com/mp3/audio_api_unavailable.mp3?extra=encodevaluefromvk"); //Encode extra url -> Good extra url
//Or see -> test.php
<?php
include_once(__DIR__ . "/perfect.php");
$email = ""; //Login
$pass = ""; //Pass
$auth_url = "https://m.vk.com";
if(array_key_exists("extra", $_GET)){
header("Content-type: audio/mpeg");
echo file_get_contents(urldecode($_GET['extra']));
}else {
/* Auth .. Copied from stackoverflow */
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $auth_url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$login_page = curl_exec($ch);
curl_close($ch);
preg_match("/<form method=\"post\" action=\"([^\"]+)/", $login_page, $login_url);
$login_url = $login_url[1];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ["email" => $email, "pass" => $pass]);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
curl_close($ch);
/* Get music */
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://m.vk.com/audio");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-Requested-With: XMLHttpRequest']);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ["_ajax" => 1, 'q' => $_GET['search']]);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$page = curl_exec($ch);
curl_close($ch);
$html = json_decode($page, true);
$html = $html[3][0];
$html = mb_convert_encoding($html, "UTF-8", "windows-1251");
preg_match_all('/<span class="ai_title">(.+?)<\/span>/', $html, $titles);
$titles = $titles[1];
preg_match_all('/<span class="ai_artist">(.+?)<\/span>/', $html, $artists);
$artists = $artists[1];
//Get extras
preg_match_all('/"https:\/\/m\.vk\.com\/mp3\/audio_api_unavailable\.mp3\?extra=([^"]+)/', $html, $extras);
$extras = $extras[1];
$result = array();
foreach ($titles as $k => $title) {
$result[] = array(
"title" => strip_tags($title),
"artist" => strip_tags($artists[$k]),
"extra" => s("https://m.vk.com/mp3/audio_api_unavailable.mp3?extra=" . $extras[$k]) //Decooooooode
);
}
/* Html */
?>
<!doctype html>
<html lang="ru">
<head>
<meta charset="windows-1251">
<title>Document</title>
</head>
<body>
<?php
echo "<table>";
foreach ($result as $val) {
echo "<tr>";
echo("<td>" . mb_convert_encoding($val['title'], "CP1251", "UTF8") . "</td><td>" . mb_convert_encoding($val['artist'], "CP1251", "UTF8") . "</td><td><a href='" . ("?extra=" . $val['extra']) . "'>Получить</a></td>");
echo "</tr>";
}
echo "</table>";
?>
</body>
</html>
<?php
}
@whakru

whakru commented Jan 13, 2022

Copy link
Copy Markdown

Всем привет, в начале 22 года не работает
случайно нет рабочего кода у кого нибудь?

Кури в сторону питона. Там есть рабочие библиотеки по ВК. К сожалению названия не помню.

@Va1b0rt

Va1b0rt commented Jan 13, 2022

Copy link
Copy Markdown

Та есть. Одна единственная. Но рабочая))

@Stmol

Stmol commented Aug 20, 2026

Copy link
Copy Markdown
<?php

declare(strict_types=1);

final class VkExtraDecoder
{
    private const ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN0PQRSTUVWXYZO123456789+/=';

    private int $userId;

    public function __construct(int $userId = 12345)
    {
        $this->userId = $userId;
    }

    public function decode(string $url): string
    {
        if (!str_contains($url, 'audio_api_unavailable')) {
            return $url;
        }

        $extra = $this->extractExtra($url);
        if ($extra === null) {
            return $url;
        }

        [$encodedPayload, $encodedCommands] = $extra;

        $payload = $this->decodeCustomBase64($encodedPayload);
        $commandsRaw = $encodedCommands !== '' ? $this->decodeCustomBase64($encodedCommands) : '';

        if (!is_string($payload) || $payload === '' || $commandsRaw === null) {
            return $url;
        }

        $commands = $commandsRaw !== '' ? explode("\t", $commandsRaw) : [];

        $current = $payload;
        foreach (array_reverse($commands) as $cmd) {
            $parts = explode("\v", $cmd);
            $op = array_shift($parts);
            $handler = $this->getHandler($op);
            if ($handler === null) {
                return $url;
            }
            $current = $handler($current, ...$parts);
        }

        return str_starts_with($current, 'http') ? $current : $url;
    }

    private function extractExtra(string $url): ?array
    {
        $pos = strpos($url, '?extra=');
        if ($pos === false) return null;

        $extra = substr($url, $pos + 7);
        [$p1, $p2] = explode('#', $extra, 2) + ['', ''];
        return [$p1, $p2];
    }

    private function decodeCustomBase64(string $data): ?string
    {
        if ($data === '' || strlen($data) % 4 === 1) {
            return null;
        }

        $alphabet = self::ALPHABET;
        $out = '';
        $t = 0;
        $o = 0;

        for ($s = 0; $s < strlen($data); $s++) {
            $i = strpos($alphabet, $data[$s]);
            if ($i === false) continue;

            $t = ($o % 4) ? 64 * $t + $i : $i;
            if ($o++ % 4) {
                $out .= chr(255 & $t >> (-2 * $o & 6));
            }
        }

        return $out;
    }

    private function getHandler(string $op): ?callable
    {
        return match ($op) {
            'v' => fn(string $e): string => strrev($e),
            'r' => fn(string $e, int $t): string => $this->shiftAlphabet($e, $t),
            's' => fn(string $e, int $t): string => $this->shuffleString($e, $t),
            'i' => fn(string $e, int $t): string => $this->shuffleString($e, $t ^ $this->userId),
            default => null,
        };
    }

    private function shiftAlphabet(string $e, int $t): string
    {
        $alphabet = self::ALPHABET . self::ALPHABET;
        $chars = str_split($e);
        foreach ($chars as $s => $c) {
            $i = stripos($alphabet, $c);
            if ($i !== false) {
                $chars[$s] = substr($alphabet, $i - $t, 1);
            }
        }
        return implode('', $chars);
    }

    private function shuffleString(string $e, int $t): string
    {
        $n = strlen($e);
        if ($n === 0) return $e;

        $perm = $this->buildPermutation($e, $t);
        $chars = str_split($e);
        for ($o = 1; $o < $n; $o++) {
            $src = $perm[$n - 1 - $o];
            $tmp = $chars[$src];
            $chars[$src] = $chars[$o];
            $chars[$o] = $tmp;
        }
        return implode('', $chars);
    }

    private function buildPermutation(string $e, int $t): array
    {
        $n = strlen($e);
        $perm = [];
        $t = abs($t);
        for ($o = $n - 1; $o >= 0; $o--) {
            $t = ($n * ($o + 1) ^ $t + $o) % $n;
            $perm[$o] = $t;
        }
        return $perm;
    }
}
$decoder = new VkExtraDecoder(12345);
$finalUrl = $decoder->decode('https://m.vk.com/mp3/audio_api_unavailable.mp3?extra=...');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment