短网址的 QR 码编码模式

Pet*_*uss 5 optimization qr-code

通常的URL 缩短技术使用通常 URL 字符集中的少数字符,因为不需要更多字符。典型的短 URLhttp://domain/code,其中代码是整数。假设我可以使用任何基数(base10、base16、base36、base62 等)来表示数字。

QR Code有多种编码模式,我们可以优化QR Code(最小版本以获得最低密度),因此我们可以测试成对的baseX-modeY...

最好的基本模式对是什么?


笔记

一个推测...

两种模式适合“URL 缩短配置文件”,

  • 0010 -字母数字编码(每2 个字符 11 位)
  • 0100-字节编码(每个字符 8 位)

我的选择是“大写 base36”和字母数字(也编码“/”、“:”等),但没有看到任何证明它始终(对于任何 URL 长度)是最好的。关于这种优化有一些好的指南或数学演示吗?

理想的(也许不切实际)

还有另一种变体,“编码模式可以根据需要在 QR 符号内混合”(维基百科)......所以,我们也可以使用

  • HTTP://DOMAIN/使用字母数字+change_mode+数字编码(每3位10位)

对于长URL(长整数),当然,这是最好的解决方案(!),因为使用所有字符集,没有松散......是吗?

问题是这种优化(混合模式)在通常的 QRCode 图像生成器中是无法访问的......它是否可行?有一台发电机使用正确吗?

另一种答案格式

(实际的)问题是关于basemode的最佳组合,因此我们可以将其表达为(例如Javascript)函数,

 function bestBaseMode(domain,number_range) {
    var dom_len = domain.length;
    var urlBase_len = dom_len+8; // 8 = "http://".length + "/".length;
    var num_min = number_range[0];
    var num_max = number_range[1];
    // ... check optimal base and mode
    return [base,mode];
 }
Run Code Online (Sandbox Code Playgroud)

示例 1:域名为“bit.ly”,代码为ISO3166-1 数字国家代码,范围从 4 到 894。因此urlBase_len=14num_min=4num_max=894

示例 2:是“postcode-resolver.org”,number_range参数是最常见的邮政编码整数表示的范围,例如从 ~999 到 ~999999 的统计推断范围。所以urlBase_len=27,num_min=999num_max=9999999.

示例 3:是“my-example3.net”,number_range是双SHA-1代码,因此是 40 字节的固定长度代码(2 个串联的十六进制 40 位长数字)。所以num_max=num_min=Math.pow(8,40)

Pet*_*uss 1

没有人想要我的赏金...我失去了它,现在还需要自己做工作;-)


关于理想

goQR.me支持回复有关混合编码的特定问题,不幸的是,它无法使用,

抱歉,我们的API不支持混合二维码编码。甚至标准也可能对其进行定义。现实世界中手机上的二维码扫描应用程序存在大量错误,我们不建议依赖此功能。

功能性答案

此功能在控制台中显示答案...这是一个简化和“强力”的解决方案。

 /**
  * Find the best base-mode pair for a short URL template as QR-Code.
  * @param Msg for debug or report.
  * @param domain the string of the internet domain
  * @param digits10 the max. number of digits in a decimal representation
  * @return array of objects with equivalent valid answers.
  */
 function bestBaseMode(msg,  domain,digits10) {
    var commomBases= [2,8,10,16,36,60,62,64,124,248];  // your config
    var dom_len = domain.length;
    var urlBase_len = dom_len+8; // 8 = "http://".length + "/".length
    var numb = parseFloat( "9".repeat(digits10) );  
    var scores = [];
    var best = 99999;
    for(i in commomBases) {
        var b  = commomBases[i];
        // formula at http://math.stackexchange.com/a/335063
        var digits = Math.floor(Math.log(numb) / Math.log(b)) + 1;
        var mode = 'alpha';
        var len = dom_len + digits;
        var lost = 0;
        if (b>36) {
            mode = 'byte';
            lost = parseInt( urlBase_len*0.25); // only 6 of 8 bits used at URL
        }
        var score = len+lost; // penalty
        scores.push({BASE:b,MODE:mode,digits:digits,score:score});
        if (score<best) best = score;
    }
    var r = [];
    for(i in scores) {
        if (scores[i].score==best) r.push(scores[i]);
    }
    return r;
}
Run Code Online (Sandbox Code Playgroud)

运行问题示例:

var x = bestBaseMode("Example-1",   "bit.ly",3);
console.log(JSON.stringify(x))   // "BASE":36,"MODE":"alpha","digits":2,"score":8

var x = bestBaseMode("Example-2",   "postcode-resolver.org",7);
console.log(JSON.stringify(x))  // "BASE":36,"MODE":"alpha","digits":5,"score":26

var x = bestBaseMode("Example-3",  "my-example3.net",97);
console.log(JSON.stringify(x))  // "BASE":248,"MODE":"byte","digits":41,"score":61
Run Code Online (Sandbox Code Playgroud)