TinyURL 的加密与解密

本文探讨了TinyURL的加密与解密方法,包括简单计数、按出现次序加密、使用HashCode、随机数以及固定长度加密等策略。各种方法在可加密数目、加密后长度、冲突可能性及预测性上各有优缺点。最后提出,无论哪种加密方式,关键在于通过一个映射关系(如map)来存储原始URL,以便于解密时查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来源

TinyURL是一种URL简化服务, 比如:当你输入一个URL https://leetcode.com/problems/design-tinyurl 时,它将返回一个简化的URL http://tinyurl.com/4e9iAk.

要求:设计一个 TinyURL 的加密 encode 和解密 decode 的方法。你的加密和解密算法如何设计和运作是没有限制的,你只需要保证一个URL可以被加密成一个TinyURL,并且这个TinyURL可以用解密方法恢复成原本的URL。

方法一:使用简单的计数

public class Codec {

    //根据次序存储加密前的url
    private Map<Integer,String> map=new HashMap<>();
    int count=0;

    //加密后的url后面根的是加密的次序,解密时根据这个次序从map中查找就可以得到原url
    public String encode(String longUrl) {
        map.put(count,longUrl);
        String shortUrl="http://tinyurl.com/"+count;
        count++;
        return shortUrl;
    }

    public String decode(String shortUrl) {
        int index = shortUrl.lastIndexOf("/");
        return map.get(Integer.valueOf(shortUrl.substring(index+1)));
    }
}

方法 2:使用出现次序加密

将url的出现次序看做62进制,将每一位映射到chars字符中,用对应的字符作为key,同时作为加密

class Codec {

    private String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private HashMap<String, String> map = new HashMap<>();
    private int count = 0;

    public String getKey() {
        int c = count;
        StringBuilder sb = new StringBuilder();
        while (c > 0) {
            c--;
            sb.append(chars.charAt(c % 62));
            c /= 62;
        }
        return sb.toString();
    }

    public String encode(String longUrl) {
        String key = getKey();
        map.put(key, longUrl);
        count++;
        return "http://tinyurl.com/" + key;
    }

    public String decode(String shortUrl) {
        int index = shortUrl.lastIndexOf("/");
        return map.get(shortUrl.substring(index + 1));
    }
}

方法一和方法二存在的问题:

  • 可加密的数目依赖int
  • 加密后的不一定更短
  • 容易预测

方法三:使用HashCode

class Codec {

    private HashMap<Integer, String> map = new HashMap<>();

    public String encode(String longUrl) {
        Integer key = longUrl.hashCode();
        map.put(key, longUrl);
        return "http://tinyurl.com/" + key;
    }

    public String decode(String shortUrl) {
        int index = shortUrl.lastIndexOf("/");
        return map.get(Integer.valueOf(shortUrl.substring(index + 1)));
    }
}

特点:

  • 加密的数目依赖int,hashCode是int的
  • 加密后的长度与原来长度没有直接关系
  • 不同的url的hashCode可能相同
  • 不容易预测

方法四:使用随机数

class Codec {

    private HashMap<Integer, String> map = new HashMap<>();
    private Random random=new Random();

    public String encode(String longUrl) {
        Integer key =random.nextInt(Integer.MAX_VALUE);
        map.put(key, longUrl);
        return "http://tinyurl.com/" + key;
    }

    public String decode(String shortUrl) {
        int index = shortUrl.lastIndexOf("/");
        return map.get(Integer.valueOf(shortUrl.substring(index + 1)));
    }
}

特点:

  • 加密的数目依赖int
  • 加密后的长度与原来长度没有直接关系
  • 可能冲突
  • 不容易预测

方法五:随机固定长度加密

class Codec {
    String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    HashMap<String, String> map = new HashMap<>();
    Random rand = new Random();

    public String getRand() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            sb.append(chars.charAt(rand.nextInt(62)));
        }
        return sb.toString();
    }

    public String encode(String longUrl) {
        String key = getRand();
        while (map.containsKey(key)) {
            key = getRand();
        }
        map.put(key, longUrl);
        return "http://tinyurl.com/" + key;
    }

    public String decode(String shortUrl) {
        int index = shortUrl.lastIndexOf("/");
        return map.get(shortUrl.substring(index + 1));
    }
}

特点:

  • 可加密数目大,也好扩展数目
  • 冲突可能小
  • 长度固定
  • 不可预测

总结
用一个map存原始url,key跟在加密后的url,解密根据这个key查找
不同的加密方法就是key的策略不同,从而影响可加密数量、长度、预测情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值