Converting short upload URLs to full URLs

I may be barking up the wrong tree here, so apologies if I am - but any pointers very much welcome!

There are some threads in our Discourse site which are displayed in part on our main website. Because the cooked version of a post contains all the HTML for the lightbox, which we don’t want on the main site, I’m working with the raw version of a post.

One thing that’s tripping me up is the file upload URLs. How can I convert an upload:// URL to a full URL? I’ve tried searching and come across SHA1 and Base62, but apart from that, no matter what I try, I can’t get the full URL.

As I said, I may looking at the wrong thing, or there’s (likely) to be an easier way to these things, so any advice welcome!

Thanks in advance

3 个赞

First base62 decode using the inverted character set, then hex encode the result.

In Python code it looks like this:

rebase = hex(base62.decode(base, base62.CHARSET_INVERTED))[2:].zfill(40)

8 个赞

Thanks for the swift reply @michaeld. Will give it a go later today :slight_smile:


For anyone interested and doing this in PHP, I used a composer library called base62 by tuupola.

This is the code I used:

<?php

$base62 = new Tuupola\Base62(["characters" => Tuupola\Base62::INVERTED]);

/** Set the original file name, excluding any file extensions */
$s = "r3AYqESanERjladb4vBB7VsMBm6";

/** Decode, convert to hex */
$decoded = $base62->decode($s);

/** Expected result: bda2c513e1da04f7b4e99230851ea2aafeb8cc4e */
echo bin2hex($decoded);
2 个赞

很有趣。我无法用 Javascript 复现这一点。因为据我所知,您最后的方法是 binary2hex 转换,但 base62 解码的结果不是二进制表示。

从 JS 的角度来看,我发现以下内容很有帮助:
https://www.npmjs.com/package/aybabtu

function fromBase62(s) {
  var digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  var result = 0;
  for (var i = 0; i < s.length; i++) {
    var p = digits.indexOf(s[i]);
    if (p < 0) {
      return NaN;
    }
    result += p * Math.pow(digits.length, s.length - i - 1);
  }
  return result;
}

不幸的是,当我使用您的输入字符串时,bin2hex 和 dec2hex 方法都没有帮助。

我为此问题创建了一个 codesandbox,有兴趣的人可以尝试一下。我的输入字符串的最终值为 1,这是错误的;(

谢谢

您应该能够使用 binVal.toString(16) 来获取十六进制值。
不过,我认为(!)中间结果太大,无法放入常规整数中。

2 个赞

感谢你的提示 Richard,但即使有了这个想法,也还是没有进展。

我不知道,是不是应该有一个类似“在原始视图(路由)中启用绝对上传链接”的设置?在我们的情况下,我绝对会使用它——因为据我所知,上传 URL 缩短只是 Discourse 的一种优化,目的是为了减少代码量,对吧?它与 Markdown 无关。

是否有 Discourse 团队的成员可以提供一个可以恢复绝对 URL 的 JS 方法?
这对社区很有帮助,请考虑一下。

我无法做到 ;(

@RGJ 你认识 Discourse 团队的人可以提供那个辅助函数吗?

不……
我建议你把这个发到 Marketplace

1 个赞

您或许可以多谈谈您的用例。也许这不是最佳解决方案。

您可以通过 base62 转换为十六进制,但如果没有某种接口连接到 Discourse 的数据库,您将永远无法完全重建上传 URL。上传的完整路径取决于上传的 id,这无法从短 URL 中确定。

正如 @pfaffman 所说,如果您能描述您的用例,我们或许能提供更多帮助。

4 个赞