短网址的二维码编码方式

QR Code encode mode for short URLs

常用URL shortening techniques use few characters of the usual URL-charset, because not need more. Typical short URL is http://domain/code, where code is a integer number. Suppose that I can use any base (base10, base16, base36、base62等)来表示数字。

QR Code have many encoding modes, and we can optimize the QR Code (minimal version to obtain lowest density), 所以我们可以测试成对的 baseX-modeY...

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


注意事项

一个猜测...

两种模式适合 "URL shortening profile",

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

理想(也许不切实际)

还有另一种变体,"encoding modes can be mixed as needed within a QR symbol"(维基百科)...因此,我们也可以使用

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

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

另一种答案格式

(可行的)问题是关于 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];
 }

示例 1: 是 "bit.ly",代码是 ISO3166-1-numeric country-code, 范围从 4 到 894。所以 urlBase_len=14num_min=4num_max=894

示例 2:domain 是 "postcode-resolver.org" 并且 number_range 参数是最常见的范围postal codes integer representations,例如统计推断的范围从 ~999 到 ~999999。所以 urlBase_len=27num_min=999num_max=9999999

示例 3: 是 "my-example3.net" 并且 number_range 是双域 SHA-1代码,所以一个固定长度的代码有 40 个字节(2 个连接的十六进制 40 位长数字)。所以 num_max=num_min=Math.pow(8,40).

没有人想要我的赏金...我把它弄丢了,现在还需要自己完成工作;-)


关于理想

goQR.me支持回复关于混合编码的特定问题记得,不幸的是,它不能使用,

sorry, our api does not support mixed qr code encoding. Even the standard may defined it. Real world QR code scanner apps on mobile phone have tons of bugs, we would not recommend to rely on this feature.

功能性答案

此功能在控制台中显示答案...这是一个简化和 "brute force" 解决方案。

 /**
  * 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;
}

运行题例:

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