视频缩略图缓存的合规短文件名编码方案咨询
视频缩略图缓存的合规短文件名编码方案咨询
我正在给lf写一个预览脚本,用chafa以sixel格式展示图片预览。目前处理视频预览时,我打算直接提取视频的第一帧作为预览图,核心逻辑是把生成的缩略图缓存到指定文件夹,避免每次都调用ffmpeg(毕竟ffmpeg处理视频还是挺慢的)。
我原本的做法是用base64编码视频文件名作为缓存PNG的文件名,代码大概是这样的:
# check if cache folder exists if [ ! -d "$cache_folder" ]; then mkdir "$cache_folder" fi # going to store thumbnail here: # not using mktemp as chafa expects a file extension thumbnail_file="$cache_folder/$(echo "$1" | base64).png" # if the thumbnail isn't cached then make it: if [ ! -f "$thumbnail_file" ]; then # get first frame of video: # the below makes the pixels square in case we have non-square pixels # which means the image won't look stretched/squished after displaying # add -y to overwrite thumbnail file if exists ffmpeg -i "$1" -vf "scale=iw*sar:ih,setsar=1" -vframes 1 -y "$thumbnail_file" &>/dev/null fi chafa -f sixel -s "$2x$3" --animate off --polite on "$thumbnail_file"
但遇到一些长文件名的视频时,会触发chafa: Failed to open [thumbnail file]: File name too long的错误,这显然是base64编码后的字符串太长导致的。现在我需要一种更合适的缓存文件名生成方式,满足这几个要求:
- 唯一性:不同视频文件不会生成相同的缓存文件名,避免预览图串用
- 足够短:不会触发文件名过长的错误(暂时没查到
chafa的具体限制,但至少要符合系统的文件名长度规范) - 合法合规:文件名里不能包含
/这类非法字符
推荐解决方案:用哈希算法替代Base64
Base64的问题在于,原文件名越长,编码后的字符串就越长,很容易超出长度限制。而哈希算法(比如MD5、SHA-256)可以把任意长度的输入转换成固定长度的字符串,完美解决这个问题,同时还能保证极低的碰撞概率(对于个人使用场景,几乎不可能出现不同文件生成相同哈希的情况)。
具体修改只需要替换生成缓存文件名的那一行:
方案1:用SHA-256哈希(64位字符,安全性更高)
thumbnail_file="$cache_folder/$(sha256sum "$1" | cut -d' ' -f1).png"
方案2:用MD5哈希(32位字符,更短)
thumbnail_file="$cache_folder/$(md5sum "$1" | cut -d' ' -f1).png"
方案3:短哈希(进一步缩短长度,个人使用足够安全)
如果觉得32位还是有点长,可以取哈希值的前16位,碰撞概率依然极低:
thumbnail_file="$cache_folder/$(sha256sum "$1" | cut -d' ' -f1 | head -c 16).png"
为什么哈希更合适?
- 长度固定:不管原文件名多长,哈希后的字符串长度都是固定的(MD5是32位,SHA-256是64位),完全不会触发文件名过长的问题
- 唯一性保障:哈希算法的碰撞概率极低,对于个人日常使用的视频文件来说,几乎不可能出现两个不同文件生成相同哈希的情况
- 合法文件名:哈希结果只包含0-9和a-f的字符,没有任何非法字符,符合所有系统的文件名规范
另外,因为你已经假设视频内容不会变化,用文件内容的哈希来生成缓存名是完全合理的——如果后续需要更新缩略图,直接删除缓存文件夹里的对应文件即可。
备注:内容来源于stack exchange,提问作者revsuine




