本文目录导读:

我来教你写一个长链接转短链接的脚本,提供几种常见的实现方式:
基于数据库的自增ID方案
Python实现
import hashlib
import string
import sqlite3
from datetime import datetime
class ShortURLGenerator:
def __init__(self, db_path='short_urls.db'):
self.conn = sqlite3.connect(db_path)
self.cursor = self.conn.cursor()
self.init_db()
def init_db(self):
self.cursor.execute('''
CREATE TABLE IF NOT EXISTS urls (
id INTEGER PRIMARY KEY AUTOINCREMENT,
long_url TEXT NOT NULL,
short_code TEXT UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
self.conn.commit()
def encode(self, num):
"""将数字转换为短码(62进制)"""
chars = string.ascii_letters + string.digits # a-z, A-Z, 0-9
if num == 0:
return chars[0]
short_code = []
while num > 0:
num, remainder = divmod(num, 62)
short_code.append(chars[remainder])
return ''.join(reversed(short_code))
def shorten(self, long_url):
"""生成短链接"""
# 检查是否已存在
self.cursor.execute('SELECT short_code FROM urls WHERE long_url = ?', (long_url,))
result = self.cursor.fetchone()
if result:
return f"http://short.url/{result[0]}"
# 插入新记录
self.cursor.execute('INSERT INTO urls (long_url) VALUES (?)', (long_url,))
self.conn.commit()
# 获取自增ID并转换
last_id = self.cursor.lastrowid
short_code = self.encode(last_id)
# 更新短码
self.cursor.execute('UPDATE urls SET short_code = ? WHERE id = ?', (short_code, last_id))
self.conn.commit()
return f"http://short.url/{short_code}"
def expand(self, short_url):
"""还原长链接"""
short_code = short_url.split('/')[-1]
self.cursor.execute('SELECT long_url FROM urls WHERE short_code = ?', (short_code,))
result = self.cursor.fetchone()
return result[0] if result else None
def close(self):
self.conn.close()
# 使用示例
if __name__ == "__main__":
generator = ShortURLGenerator()
# 生成短链接
long_url = "https://www.example.com/very/long/url/that/needs/to/be/shortened"
short_url = generator.shorten(long_url)
print(f"长链接: {long_url}")
print(f"短链接: {short_url}")
# 还原长链接
original_url = generator.expand(short_url)
print(f"还原: {original_url}")
generator.close()
基于哈希的短链接生成
import hashlib
import base64
class HashShortURLGenerator:
def __init__(self, length=6):
self.length = length
self.url_map = {}
self.collision_map = {}
def generate_hash(self, long_url, salt=""):
"""生成短哈希码"""
# 使用MD5生成哈希
hash_input = long_url + salt
md5_hash = hashlib.md5(hash_input.encode()).hexdigest()
# 取前length位作为短码
short_code = md5_hash[:self.length]
return short_code
def shorten(self, long_url):
"""生成短链接"""
short_code = self.generate_hash(long_url)
# 处理冲突
counter = 0
while short_code in self.url_map and self.url_map[short_code] != long_url:
counter += 1
short_code = self.generate_hash(long_url, str(counter))
self.url_map[short_code] = long_url
return f"http://short.url/{short_code}"
def expand(self, short_url):
"""还原长链接"""
short_code = short_url.split('/')[-1]
return self.url_map.get(short_code)
# 使用示例
hash_generator = HashShortURLGenerator()
long_url = "https://www.example.com/very/long/url"
short_url = hash_generator.shorten(long_url)
print(f"哈希短链接: {short_url}")
print(f"还原: {hash_generator.expand(short_url)}")
简单的命令行脚本
#!/usr/bin/env python3
import sys
import hashlib
import json
import os
class SimpleShortURL:
def __init__(self, data_file='short_urls.json'):
self.data_file = data_file
self.urls = self.load_data()
def load_data(self):
if os.path.exists(self.data_file):
with open(self.data_file, 'r') as f:
return json.load(f)
return {}
def save_data(self):
with open(self.data_file, 'w') as f:
json.dump(self.urls, f, indent=2)
def generate_short_code(self):
"""生成8位随机短码"""
import random
import string
chars = string.ascii_letters + string.digits
return ''.join(random.choice(chars) for _ in range(8))
def shorten(self, long_url):
# 检查是否已存在
for code, url in self.urls.items():
if url == long_url:
return code
# 生成新短码
short_code = self.generate_short_code()
while short_code in self.urls:
short_code = self.generate_short_code()
self.urls[short_code] = long_url
self.save_data()
return short_code
def expand(self, short_code):
return self.urls.get(short_code)
def main():
shortener = SimpleShortURL()
if len(sys.argv) < 2:
print("使用方法:")
print(f" {sys.argv[0]} shorten <长链接> - 生成短链接")
print(f" {sys.argv[0]} expand <短码> - 还原长链接")
return
command = sys.argv[1]
if command == "shorten" and len(sys.argv) >= 3:
long_url = sys.argv[2]
short_code = shortener.shorten(long_url)
print(f"短链接: http://short.url/{short_code}")
elif command == "expand" and len(sys.argv) >= 3:
short_code = sys.argv[2]
long_url = shortener.expand(short_code)
if long_url:
print(f"长链接: {long_url}")
else:
print("未找到对应的长链接")
else:
print("无效命令")
if __name__ == "__main__":
main()
API版本的短链接服务
# Flask版本的短链接服务API
from flask import Flask, request, jsonify, redirect
import hashlib
import string
from datetime import datetime
app = Flask(__name__)
# 内存存储(实际应用中应使用数据库)
url_store = {}
def generate_short_code(long_url, length=6):
"""生成短码"""
hash_input = f"{long_url}{datetime.now().timestamp()}"
md5_hash = hashlib.md5(hash_input.encode()).hexdigest()
# 确保唯一性
short_code = md5_hash[:length]
while short_code in url_store:
hash_input += "1"
md5_hash = hashlib.md5(hash_input.encode()).hexdigest()
short_code = md5_hash[:length]
return short_code
@app.route('/shorten', methods=['POST'])
def shorten_url():
"""生成短链接API"""
data = request.get_json()
if not data or 'url' not in data:
return jsonify({'error': '请提供url参数'}), 400
long_url = data['url']
# 检查是否已存在
for code, url in url_store.items():
if url == long_url:
return jsonify({
'short_url': f'/s/{code}',
'long_url': long_url
})
# 生成新短链接
short_code = generate_short_code(long_url)
url_store[short_code] = {
'long_url': long_url,
'created_at': datetime.now().isoformat(),
'clicks': 0
}
return jsonify({
'short_url': f'/s/{short_code}',
'long_url': long_url
})
@app.route('/s/<short_code>')
def redirect_to_url(short_code):
"""短链接重定向"""
url_data = url_store.get(short_code)
if url_data:
# 增加点击计数
url_data['clicks'] += 1
return redirect(url_data['long_url'])
return jsonify({'error': '短链接不存在'}), 404
@app.route('/info/<short_code>')
def get_url_info(short_code):
"""获取短链接信息"""
url_data = url_store.get(short_code)
if url_data:
return jsonify(url_data)
return jsonify({'error': '短链接不存在'}), 404
if __name__ == '__main__':
app.run(debug=True, port=5000)
使用方法
- 数据库版本:直接运行会创建SQLite数据库存储映射关系
- 哈希版本:简单的内存缓存,适合测试
- 命令行版本:
python short_url.py shorten "https://example.com/long-url" - API版本:启动Flask服务后,POST请求到
/shorten
选择哪种方案取决于你的具体需求:
- 生产环境推荐数据库版本,可持久化存储
- 简单使用推荐命令行版本
- 微服务推荐API版本
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播