古诗色韵:用SHA-1算法为古典诗词生成专属色谱

代码与古诗的色彩对话,解码每日诗词的色彩基因图谱

项目起源

我一直好奇:如果给每首古诗一个「颜色签名」会怎样?不是主观的艺术创作,而是通过确定的算法,让每首诗都能生成独特的、可复现的色彩组合。

于是有了「古诗色韵」项目——用SHA-1哈希算法将诗词文本转化为视觉色谱。

技术原理

1. SHA-1:从文字到数字指纹

SHA-1(安全哈希算法1)会为任何输入生成一个40位的十六进制字符串(160位二进制)。关键特性:

  • 确定性:相同输入永远得到相同输出
  • 雪崩效应:微小改动导致结果天差地别
  • 不可逆:无法从哈希值反推原文
1
2
3
4
5
6
7
8
// SHA-1计算函数
async function sha1(str) {
const encoder = new TextEncoder();
const data = encoder.encode(str);
const hashBuffer = await crypto.subtle.digest('SHA-1', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}

2. 从哈希值到颜色值

SHA-1的40个十六进制字符,每6个字符可以构成一个CSS颜色值:

1
2
3
4
5
6
7
8
9
10
11
12
async function generateColors(text, numColors = 5) {
const hash = await sha1(text);
const colors = [];

for (let i = 0; i < numColors; i++) {
const start = (i * 6) % 34; // 滑动窗口提取
const colorHex = "#" + hash.substring(start, start + 6);
colors.push(colorHex);
}

return colors;
}

提取逻辑

  • 第1色:字符0-5 → #2aae6c
  • 第2色:字符6-11 → #35c94f
  • 第3色:字符12-17 → #cfb415
  • 以此类推…

3. 诗词解析

以宋代刘过的《唐多令》为例:

1
2
3
4
5
6
7
8
唐多令
宋代 · 刘过
芦叶满汀洲,寒沙带浅流。
二十年重过南楼。
柳下系船犹未稳,能几日,又中秋。
黄鹤断矶头,故人今在否?
旧江山浑是新愁。
欲买桂花同载酒,终不似、少年游。

我们分别提取:

  • 标题:《唐多令》
  • 作者:刘过
  • 各分句诗词
  • 全诗整体

实战演示:《唐多令》的色彩基因

原始数据

  • 标题:唐多令 → SHA-1: 99ec54902060ec981a...
  • 作者:刘过 → SHA-1: 5630828ac3d4b40e7a...
  • 全诗:完整文本 → SHA-1: f6f32b26f65144ea00...

生成的色谱展示

1. 《唐多令》的题目色彩
1
颜色值:#99ec54 → #902060 → #ec981a
2. 刘过的色彩
1
颜色值:#563082 → #8ac3d4 → #b40e7a
3. 分句色谱
4. 全诗整体色彩
1
5色渐变:#f6f32b → #26f651 → #44ea00 → #fbdcbb → #3727df

技术细节

为什么选择SHA-1?

  1. 固定长度:始终40个十六进制字符,便于颜色提取
  2. 足够分散:哈希冲突概率极低(约1/2^80)
  3. 广泛支持:所有现代浏览器都原生支持
  4. 适度安全:虽然密码学上已被淘汰,但对本项目足够

颜色提取算法

1
2
3
4
5
6
// 关键算法:滑动窗口提取
const start = (i * 6) % 34;

// 为什么是%34?
// 40个字符 - 6个字符/颜色 = 34
// 确保提取不越界,且能循环利用哈希值

为什么不是随机颜色?

  • 可复现性:同一首诗永远生成相同颜色
  • 文本关联:颜色直接源于文本的「数字DNA」
  • 确定之美:算法美学强调过程而非结果随机

应用场景

  1. 数字藏书票:为电子版古籍生成视觉标识
  2. 诗词可视化:将文学韵律转化为色彩韵律
  3. 教育工具:让学生「看见」诗词的结构
  4. 艺术创作:算法生成的色卡用于设计

代码实现

完整的工作流代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 核心代码片段
async function processPoem(poemText) {
// 1. 解析诗词结构
const {title, author, lines} = parsePoem(poemText);

// 2. 生成各部分的颜色
const titleColors = await generateColors(title, 3);
const authorColors = await generateColors(author, 3);
const lineColors = await Promise.all(lines.map(line => generateColors(line, 3)));
const fullColors = await generateColors(lines.join(''), 5);

// 3. 生成HTML可视化
return generateVisualization({
title, author, lines,
titleColors, authorColors, lineColors, fullColors
});
}

延伸思考

这个项目让我想到几个有趣的方向:

1. 不同哈希算法的比较

  • SHA-256:64字符,更多颜色组合
  • MD5:32字符
  • 自定义算法:针对诗词特性优化

2. 颜色空间的拓展

目前使用RGB十六进制,可尝试:

  • HSL色彩空间:控制饱和度、亮度
  • LAB色彩空间:更符合人眼感知
  • 中国传统色彩体系:绛红、月白、黛青…

3. 动态可视化

  • 随着诗词朗读,颜色流动变化
  • 交互式探索:点击色块查看对应诗句
  • 时间维度:不同时期的诗词色彩演变

最后

「古诗色韵」不是要用算法取代艺术,而是寻找技术与人文的新对话方式。当SHA-1遇上《唐多令》,当十六进制代码遇见「芦叶满汀洲」,我们看到的是数字时代对古典美学的重新解读。

每首古诗都有其独特的「色彩基因」,而我们只是用代码让这些基因「显形」罢了。