专栏名称: 吴师兄学算法
和程序员小吴一起从初学者的角度学习算法,以动画的形式呈现解题的思路。每周四篇原创文章,期待你的鉴赏!
目录
相关文章推荐
Excel之家ExcelHome  ·  AI时代Excel会被淘汰?LOOKUP函数 ... ·  2 天前  
完美Excel  ·  使用deepseek在Excel用户窗体中生 ... ·  2 天前  
Excel之家ExcelHome  ·  WPS表格中的几个实用功能 ·  4 天前  
Excel之家ExcelHome  ·  让Excel自动检测录入的数据 ·  3 天前  
Excel之家ExcelHome  ·  还在手动筛选数据?FILTER函数这几种典型 ... ·  3 天前  
51好读  ›  专栏  ›  吴师兄学算法

世界果然都是一个草台班子。。。

吴师兄学算法  · 公众号  ·  · 2024-10-02 20:19

正文

大家好,我是吴师兄。

最近发生的一系列事件让我越来越坚信, 世界果然都是一个草台班子

无论是游戏、股票市场,还是顶尖科技公司,大家所仰望的那些“大牌”,实际上也经常暴露出让人啼笑皆非的问题。这不仅让我开始反思: 我们是否过度神话了那些所谓的巨头

举个例子,国服《炉石传说》刚回归,大家都满怀期待,结果服务器却频繁崩溃,官方给出的理由竟然是“ 玩家人数太多,底层服务器承受不住,出现了意想不到的 bug ”。

这就像你去参加一场高规格的晚宴,结果主办方居然没有足够的餐具。

就连道歉的过程还是高高在上的姿态。

再看 A 股市场,最近因为行情火热,上交所的系统甚至被挤爆,连这样关键的基础设施在高压之下也会出现问题。

而更令人惊讶的是,Meta(也就是之前的Facebook)居然和 CSDN 一样,曾经明文存储用户密码。作为全球科技巨头,这种低级错误让人不禁怀疑,连他们都不例外吗?

这些例子让我不得不开始质疑我们对大型公司的技术水平的期待。

无论是游戏公司、金融市场,还是科技巨头,都没有我们想象中的那么完美。或许,每一个行业的背后,都藏着我们看不到的“草台班子”运作。

漏洞不仅仅存在,而且往往出现在我们最意想不到的地方。

因此,越来越多的人,包括我自己,开始接受一个现实: 世界并非是一个完美的体系,无论规模多大、技术多先进的公司,背后也有着这样那样的隐患

我们常常认为,像 Meta 这样的科技巨头在用户数据保护上一定是高标准,但现实却一次次打破这种神话。当我们回顾这些事件时,发现很多时候我们对技术的认知存在误区,甚至连一些基础概念都被误解和滥用。

其中一个典型的例子就是 MD5 。

MD5往往被很多人误认为是一种“加密算法”,但实际上它并不具备真正的加密功能。

MD5的原本设计是用于数据的完整性校验,也就是说,它的主要功能是将一段数据通过算法转换为一串固定长度的哈希值,用来确认数据是否被篡改。

然而,随着时间的推移,MD5逐渐被滥用于加密场景,但这显然是不合适的。尤其是在互联网和信息安全领域,MD5的安全性已经被证明不再可靠,原因就在于它容易被破解或碰撞攻击。

然而令人意外的是,很多公司仍在使用MD5,甚至是以“加密”的方式进行用户密码的存储,这无疑是一种技术滥用和误解。

正如前面提到的那些漏洞一样,巨头公司表面看起来无懈可击,但实际上也会因为技术上的疏忽或误解,导致安全隐患。

尤其是当我们谈论“加密”时,更需要明确知道什么是安全的,什么是已经过时的。

接下来,我想简单聊一聊,为什么MD5不能算作加密算法,它和真正的加密算法之间到底有哪些本质区别。

一、MD5算法

MD5 即 Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一,主流编程语言普遍已有 MD5 实现。

将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理, MD5 的前身有 MD2 、MD3 和 MD4 。

MD5 是输入不定长度信息,输出固定长度 128-bits 的算法。经过程序流程,生成四个32位数据,最后联合起来成为一个 128-bits 散列。

基本方式为,求余、取余、调整长度、与链接变量进行循环运算,得出结果。

MD5 计算广泛应用于错误检查。在一些 BitTorrent 下载中,软件通过计算 MD5 来检验下载到的碎片的完整性。

二、加密算法

百度百科 :加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容。

维基百科 :在密码学中, 加密 (英语:Encryption)是将明文信息改变为难以读取的密文内容,使之不可读的过程。只有拥有解密方法的对象,经由解密过程,才能将密文还原为正常可读的内容。

三、对比

也就是说,MD5 算法和加密算法都可以将信息转换为另外一种内容。

但是, MD5 算法 对比 加密算法 缺少了解密过程。

事实上,使用 加密算法 加密后的消息是完整的,并且基于解密算法后,可以恢复原始数据。

MD5 算法 得到的消息是不完整的,并且通过摘要的数据也无法得到原始数据。

所以, MD5 算法不是加密算法

...

回归我们公众号的主题。

继续来一道和「大厂秋招」相关的算法原题。

题目描述

给定一段"密文"字符串 s ,其中字符都是经过"密码本"映射的,现需要将"密文"解密并且输出。

映射的规则 : "a-i" 分别用 "1-9" 表示, "j-z" 分别用 "10*-26*" 表示

约束:映射始终唯一

输入描述

“密文”字符串

输出描述

明文字符串

补充说明

翻译后的文本的长度在 100 以内

示例一

输入

20*19*20*

输出

tst

示例二

输入

12320*12319*20*

输出

abctabcst

解题思路

本题需要分两步走:对原字符串的预处理以及元素映射关系。

元素映射

涉及元素一一映射的关系,构建从数字到字母的映射这件事, 很容易想到应该使用哈希表来解决

为了构建数字和字母之间的映射,可以使用ASCII码值来完成。使用 ord("a") 可以计算得到字符 "a" 的ASCII码值,选定数字 i 的范围为 [1, 26] ,则 ord("a")+i-1 可以得到所有小写字母的ASCII码值,再使用 chr() 内置函数将ASCII码值转换回小写字母,即 chr(ord("a")+i-1) 。故构建映射关系哈希表的代码为

dic = {str(i): chr(ord("a") + i - 1for i in range(127)}

两位数的处理

另外,本题所给密码字符串中,两位数( 10-26 )的后面都会带一个 * ,而一位数( 1-9 )的后面不带 * ,我们必须把这两种情况区分开来。

如果我们从头到尾地遍历原字符串 s ,每次遇到一个 * 号,则说明此时 * 号前面的两个字符需要合并在一起,视为一个两位数来处理。

很显然,只有在遇到 * 号的时候,才需要去查看刚刚 最新遇到的两个数字字符 ,这是一种后进先出的思路,很显然可以使用栈来处理这个过程。其过程如下

stack = list()

for ch in s:
    if ch == "*":
        digit_1 = stack.pop()
        digit_10 = stack.pop()
        stack.append(digit_10 + digit_1)
    else:
        stack.append(ch)

退出循环后,栈中储存了若干个数字字符串(有一位数也有两位数),再将这些数字字符串传入哈希表中进行从数字到字母的映射,再合并为一个字符串输出即为答案。代码如下

print("".join(dic[num_str] for num_str in stack))

代码

Python

# 关注吴师兄,算法学习好轻松
# 构建数字和字母之间的映射关系
dic = {str(i): chr(ord("a") + i - 1for i in range(127)}

# 输入字符串
s = input()

# 构建一个栈
stack = list()

# 遍历s中所有字符
for ch in s:
    # 如果是*号,说明*前面的两个数字要合并为一个两位数一起考虑
    if ch == "*":
        # 弹出栈顶两个元素,分别是个位和十位的字符串
        # 先弹出个位,再弹出10位
        digit_1 = stack.pop()
        digit_10 = stack.pop()
        # 将合并后的两位数重新压回栈顶
        stack.append(digit_10 + digit_1)
    # 如果不是*号,而是数字,则直接入栈
    else:
        stack.append(ch)

# 最后栈中的所有元素即为数字字符串,使用dic进行从数字到字母的映射之后再合并即可
print("".join(dic[num_str] for num_str in stack))

Java

import java.util.HashMap;
import java.util.Scanner;
import java.util.Stack;

public






请到「今天看啥」查看全文