简介:一份关于软件著作权源代码的知识解读型DOC文档,面向软件开发者、版权管理人员及准备申请软件著作权的个人或团队,用于理解源代码在著作权保护中的核心地位、开源与专有代码的区分,以及代码编写规范、注释、日志记录、条件编译等与版权归属相关的实践要素。该文档共1个文件,类型为DOC,压缩包大小188KB,内容节选了实际C/C++代码片段,并围绕其展开对宏定义、预处理指令、程序配置信息、调试日志等细节的梳理,适合作为源代码文档整理与著作权申请前的参考笔记。目前已有109人学习下载。通过这份文档,读者可以快速掌握软件著作权源代码文档应关注的关键维度,如版权声明位置、版本与配置信息识别、代码风格与可维护性等,有助于在实际开发中规范源代码管理并为后续维权或申报积累完整证据。
1. “软件著作权源代码.doc”到底卡在哪
准备过软件著作权申报的人,对“软件著作权源代码.doc”不会陌生。它就是登记材料里必须提交的那份源程序文档:从前、后各取连续30页,每页不少于50行,页眉写软件名称和版本号,页码放在右上角。很多开发者最后被退回,不是代码写得不好,而是这份doc的行数、页眉、连续性没对上要求。
这里按版权保护中心现行的登记指南拆格式点:先讲页数、行数、页码这些硬指标,再给从工程里提取代码、算行数的Python预处理方案,最后落到Word排版参数和提交前的PDF逐页核验。适合第一次自己办软著的技术人,也适合替客户整理申报材料、但没把所有坑走完的代理人。
如果系统已经写完,只差把源码整理成能提交的doc,可以直接从第3章开始;如果连模块顺序都没定,建议先把第2章读完。
2. 软著源代码文档的硬性规范:60页、50行与页眉页码
2.1 前、后各连续30页是如何计算的
版权保护中心目前的源程序材料要求,核心一句话:源程序前、后各连续30页,共60页;每页不少于50行,最后一页不足50行可以。所谓“前30页”,是按你最终提交的代码顺序,从第1页数到第30页;“后30页”是从倒数第1页往前数30页。如果整个项目不足60页,就把全部源代码提交上去,不再拆前后。
这里的“页”有歧义。有人习惯先按行数算出3000行,再平均分到60页;实际上页数由Word分页结果决定,不是由3000行硬切出来的。3000行 ÷ 50行/页 = 60页只在行距、页边距都受控时成立。只要行距忽大忽小,1500行可能排成31页或29页,所以最终要以PDF导出后的实际页码为准。
用一个简单公式估算:A4纸高度29.7cm,上下边距各2.54cm,正文可用高度约24.6cm。如果行距固定为13磅,1磅约0.0353cm,13磅约0.459cm,每页能排约53.6行。设置成固定值13磅后,1100行大约排到第21页,而不是字面意义的第22页。
2.2 每页不少于50行,到底哪些行算
规范正文没有说“空行必须删除”,但实际操作里,审查员对页面的观感很重要。一页满屏注释或十几行空行,页面的有效代码密度会被认为不够。所以我按“有效代码行”来控制:空行、只含空白字符的行不计入50行;注释行可以保留,尤其是文件头说明和关键函数注释,它们是判断源程序真实性的一部分。
分页细节也容易踩坑。Word默认允许段中分页,一段代码可能从页面中间断开,上一页末尾只剩两行。如果这两行恰好让上一页的有效行数低于50,就要调整分页。常见做法是在段前加分页符,或者把该页之前的一处空行压缩掉,让自然分页点落在代码块之间。不要为了凑行数去复制重复代码或在行尾敲空格,这在材料审核时一眼能看出来。
2.3 页眉、页码与版本号的常见格式
版权保护中心要求源程序页眉标注“软件名称+版本号”,右上角标注页码。常见模板是页眉左侧写“系统简称 V1.0”,页眉右侧写“第 X 页”;也有的模板把页码放页脚右侧,但按指南表述,放在右上角更稳妥。
我建议第一页就从代码开始,不加封面、不加目录。封面和目录会计入页数,跟你数前30页、后30页造成干扰。页眉用Word的域字段生成页码,不要手工输入数字,否则插删一行后页码会错乱。
| 对象 | 推荐设置 | 说明 |
|---|---|---|
| 页数 | 前、后各30页,不足60页全交 | 以PDF实际分页为准 |
| 每页行数 | 不少于50行,末页可不足 | 空行不算,注释算 |
| 页眉 | 软件全称+版本号 | 中英文统一 |
| 页码 | 右上角,用域字段 | 不要手工敲数字 |
| 字体 | 宋体/等宽字体,五号或小五 | 太小会被认为不清晰 |
| 行距 | 固定值12-13磅 | 保证每页50行以上 |
围绕这张表,提交前只需要回答三个问题:软件名和版本号是否和申请表一致?页码是否能连续?每一页的有效行数是否达到50?这三个问题在后面的核验章节还会再过一遍。
3. 源代码选段与前处理:先算清行数再动 Word
3.1 用文件顺序还是“核心模块优先”
前30页和后30页强调“连续”,不是随机拼接。常规做法是先确定一份源码顺序清单,再按这个顺序把文件内容拼成一份临时文本。清单顺序一般按项目的目录结构走:入口文件、配置定义、业务模块、工具类放在最后;也可以按你向版权中心提交的软件说明书里描述的核心功能顺序走。
判断标准是:审查员拿到这份doc,能不能按顺序看到一个软件从启动到核心业务处理的大致脉络。所以不要只挑算法文件,也不要按文件名首字母排然后把日志模块放在第一页。遇到前后端分离项目,我一般会选取后端主体作为源程序主线,前端页面文件作为补充,不把SQL脚本和初始化数据作为主要材料,因为那些不是源程序的主体。
候选文件选定后,要剔除这些内容:node_modules、dist、build、.git、pycache等依赖和构建产物;lock 文件;自动生成的 protobuf 和 API 客户端;体积巨大的测试数据。保留测试代码没问题,但不能让它占用前30页的主要篇幅。过长的空注释块、IDE 生成的====分隔线也顺手删掉,这些在Word里算一行但没有任何信息量。
3.2 用 Python 把源码拼成前30页和后30页
下面这个脚本解决“到底取哪些行”的问题。它按扩展名白名单收集文件,按目录顺序排序,剔除空行,再把总行数切成前1500行和后1500行,输出成 head.txt 和 tail.txt。1500行是30页×50行的基准,最后用Word排版时,页数会在大约60页上下浮动。
#!/usr/bin/env python3 # split_source_for_copyright.py import sys from pathlib import Path CODE_EXTS = { ".py", ".js", ".ts", ".java", ".c", ".cpp", ".h", ".hpp", ".go", ".rb", ".php", ".sql", ".vue", ".jsx", ".tsx", } SKIP_DIRS = {"node_modules", "dist", "build", ".git", "__pycache__", "venv", ".idea"} SKIP_FILES = {"package-lock.json", "yarn.lock", "pnpm-lock.yaml", "go.sum"} def is_code_file(path: Path) -> bool: if path.suffix.lower() not in CODE_EXTS: return False if any(part in SKIP_DIRS for part in path.parts): return False return path.name not in SKIP_FILES def collect_lines(root: Path): files = [p for p in root.rglob("*") if p.is_file() and is_code_file(p)] files.sort(key=lambda p: str(p).relative_to(root).lower()) lines = [] for f in files: try: text = f.read_text(encoding="utf-8", errors="ignore") except OSError: continue for raw in text.splitlines(): if raw.strip(): lines.append(raw) return files, lines def main() -> None: root = Path(sys.argv[1] if len(sys.argv) > 1 else ".") files, lines = collect_lines(root) total = len(lines) per_page, pages = 50, 30 limit = per_page * pages print(f"找到 {len(files)} 个代码文件,有效行数 {total}") if total <= limit * 2: Path("source.txt").write_text("\n".join(lines), encoding="utf-8") print("不足60页基准,已输出 source.txt,提交时全文导入") else: head = lines[:limit] tail = lines[-limit:] Path("head.txt").write_text("\n".join(head), encoding="utf-8") Path("tail.txt").write_text("\n".join(tail), encoding="utf-8") print("已输出 head.txt 和 tail.txt,两者在Word中按顺序导入") if __name__ == "__main__": main()脚本逻辑分三层。第一层用扩展名和目录名做过滤,errors="ignore"避免单个文件编码异常导致整个合并中断。第二层对文件列表排序后逐文件读取,text.splitlines()把物理行拆开,raw.strip()为假时跳过,保证输出里没有空行。第三层按行切片,head 取第0行到第1499行,tail 取倒数第1500行到末尾。
这里要留意:errors="ignore"只适合预处理。如果你的代码是GBK编码却按UTF-8读取,中文字符串会变成乱码。遇到中文注释多的情况,先统一把工程代码转成UTF-8,再用脚本处理。另外脚本没有在head和tail之间插入任何“中间部分省略”的标记,提交文档里也不需要这个说明。
3.3 行数基准和文件顺序怎么按需调整
如果你不想让脚本的排序决定一切,可以先读一遍文件清单,把入口文件、核心模块文件手动挪到列表前面,再决定 head/tail 切点。这就是“连续30页”的人工把握部分:同一文件的行要自然连续,一个文件在 head 里只出现一次,不要把同一个A文件倒着拼接。
有些项目总行数在3500行左右,head取1500、tail取1500后,中间还有500行不出现,这是符合规则的。如果总行数只有3100行,head和tail之间只差100行,仍按前1500、后1500处理。不要为了让 tail 看起来完整,强行把 head 缩到1200行,那样第30页的有效行数很可能会跌破50。
4. doc 排版实操:字体、固定行距、页眉页码与导入顺序
4.1 新建空白 doc 并设置页面和代码样式
打开Word或WPS,先新建一个空白文档。不要先把源码粘进去再调格式,那样样式的修改量很大。按这组参数先设置页面:A4;页边距上2.54cm、下2.54cm、左2.6cm、右2.6cm;页眉距边界1.5cm;页脚距边界1.75cm。左右边距比Word默认的3.17cm略窄,长代码行能多容纳几个字符。
接下来定义一个“源代码”段落样式。字体用中文宋体、西文Consolas,字号五号,段落行距设为固定值13磅。中文字体决定中文注释的显示,西文字体决定代码里 ASCII 字符的对齐效果。行距固定值13磅的理论行数约53行,满足“不少于50行”且不会挤到难以阅读。如果一页排下来只有51行,那是段落分页造成的轻微损耗,还在安全线内。
不要把行距设成“最小值”或“单倍行距”。代码里一行有大小写字母和中文混排时,Word会自动把行加高,造成每页行数波动。固定值能让每一行高度严格一致,分页结果才稳定。
| 排版参数 | 推荐值 | 为什么这么定 |
|---|---|---|
| 纸张 | A4 | 各地登记窗口统一要求 |
| 上下边距 | 2.54cm | 正文可用高度约24.6cm |
| 左右边距 | 2.6cm | 比默认3.17cm窄,长行不易折行 |
| 字体 | 中文宋体、西文Consolas | 中文注释不乱码,ASCII等宽 |
| 字号 | 五号 | 打印清晰,不会被判定为不清晰 |
| 行距 | 固定值13磅 | 每行约0.459cm,单页约53行 |
4.2 用“文件中的文字”导入两个分段
脚本输出的是纯文本文件,Word的“插入 → 对象 → 文件中的文字”可以直接读取。光标定位到正文开头,选择插入对象中的“文件中的文字”,选中 head.txt 后确认;再把光标移到文档末尾,同样方式导入 tail.txt。如果不足60页的情况,则只导入 source.txt 一个文件。
如果你用的是WPS,入口在“插入 → 对象 → 文件中的文字”,行为一致。导入后立刻全选,套用刚才定义好的“源代码”样式。纯文本里的Tab会被保留,建议在代码源文件里先把Tab替换成4个空格。Tab宽度在Word和代码编辑器里不一致,等宽字体也救不回来。替换方法是先在代码编辑器里做全局替换,再生成txt;不要在Word里直接用“查找和替换”处理全部内容,容易误伤字符串字面量。
导入后的常见问题有两个。一是中文乱码,把 head.txt/tail.txt 用带BOM的UTF-8编码另存一次,再重新导入;二是行数不对,导入后每页可能只有40行,因为默认样式还是Word的正文样式而不是“源代码”样式。全选文本后再次确认段落对话框里行距是固定值13磅。
如果路径固定、需要反复生成材料,也可以录一个简单的VBA宏:
Sub ImportSourceCode() Dim dirPath As String dirPath = "C:\temp\" Selection.HomeKey Unit:=wdStory Selection.InsertFile FileName:=dirPath & "head.txt" Selection.EndKey Unit:=wdStory Selection.InsertFile FileName:=dirPath & "tail.txt" Selection.WholeStory With Selection.ParagraphFormat .LineSpacingRule = wdLineSpaceExactly .LineSpacing = 13 End With End Sub这段宏做了三件事:回到文档开头,用InsertFile插入head.txt;移动到文档末尾再插入tail.txt;全选后把段落行距设为固定值13磅。wdStory是Word内置常量,代表文档的起点或终点;wdLineSpaceExactly对应“固定值”行距规则。使用前把dirPath改成你存放txt文件的目录,否则会报文件找不到的错误。
4.3 页眉页码从正文第一页开始连续
双击页面顶部进入页眉编辑区。左侧输入“软件名称 V1.0”,这里必须和申请表里的软件全称、版本号一致,不能用项目目录名替换。然后在这一行设置右对齐制表位,位置取纸张宽度减去左右边距,大约14.5cm处。按Tab把光标推到右侧,用“插入 → 域 → Page”插入页码字段,显示效果为“第 1 页”。
页码不要自己打数字。域字段Page会按实际分页自动编号,删掉或增加一行后页码仍然连续。如果第1页内容比较特殊,想要从第2页才开始显示页眉,则需要在第1页末尾插入分节符,再取消第1节“链接到前一节”。如果全文档都使用同一套页眉,就不需要处理分节。
先填页眉还是先导入代码,顺序没有硬性要求。我习惯先导入代码并确认分页,再处理页眉页码,避免改动正文时把页眉里的手工编号改漏。处理完页眉后,用Ctrl+Home回到第一页,逐页翻一遍版式,确认右边距没有代码被切掉。
4.4 长行折行和跨页断行的影响
代码里一行超过页面宽度时,Word会把这一行自动折成两个显示行,打印行数就从1行变成2行。这会让每页看起来比实际多,同时也可能把下一行代码推到下一页,造成新一页开头只有孤零零的几行代码。
处理方式有两种。代码行本身超过80个字符的,在源码层改成多行写法。Python用括号隐式接行,C/Java在运算符后换行,SQL用子查询分层。另一种是缩小字体,五号改成小五,但字符太小会影响阅读观感。我一般优先改代码,因为重构后的代码在业务层面也是正常写法,不是专门为申报伪造的。
另外不要勾选段落格式里的“与下段同页”和“段中不分页”。源代码每个函数往往很长,任何一段都没有必要整体保持在一页内。勾了这两个选项,Word会把一大段完整推到下一页,上一页末尾留下一大块空白,直接导致有效行数不足50。
5. 提交前用 PDF 逐页验收:行数自查与两处回改
5.1 用 pdfplumber 逐页统计有效行数
先把最终文档另存为PDF。即便你用的是WPS,导出时也选“PDF”而不是“打印到PDF”,后者容易嵌入打印机字体信息,可能改变分页。安装依赖后,用 pdfplumber 对每一页做文字抽取,统计除去页眉后的正文行数:
import sys import pdfplumber with pdfplumber.open(sys.argv[1]) as pdf: for idx, page in enumerate(pdf.pages, 1): text = page.extract_text() or "" raw = [ln for ln in text.splitlines() if ln.strip()] body = raw[1:] if len(raw) > 1 else raw print(f"第{idx:02d}页: 正文{len(body)}行, 抽取{len(raw)}行")脚本只做两件事:extract_text()把当前页文本按行拆分,raw[1:]删掉第一行。页眉通常在首行,去掉后剩下的是代码正文。如果你的页码做成页脚,页脚会出现在末行,需要把切片改成raw[1:-1]。我这里按“页码在页眉右上角”的模板只去掉首行。
统计结果里如果出现某页低于50行,先翻到那一页看版式,通常原因是长代码折行把后续行推到下一页,或插入了额外空页。还有一种情况是段前没设置分页,代码段在上一页底部只剩一行,导致上一页有效行数掉到49。这时不要整体调行距,直接在上一页末尾插入分页符,让新页从完整代码块开始。
5.2 两个高频回改点
第一处是页首孤行。一个函数的最后一行被推到新页,该页开头只有两三行代码。解决办法是在上一页的代码块之间插入分页符,让新页从完整函数开始。第二处是页眉里的软件名称和申请表不一致,比如项目目录叫 order-api,页眉却写了“订单系统”,审查员会认为材料主体不一致。页眉必须在最后核对一遍软件全称和版本号,和申请表一字不差。
还可以抽查中间是否有纯空白页。如果页码从2直接跳到4,多半是插入了分页符导致空白页。打开Word的显示/隐藏编辑标记,找到空页里的分页符删掉。最后再强调一遍:页码右上角、每页50行、前后各30页,这三个点不解决,源代码再真实也会被窗口退回。核对完这一遍,这份“软件著作权源代码.doc”就可以直接进入递交队列了。
本文还有配套的精品资源,点击获取