文章目录

  • 前言
  • 一、Week1 PA
    • 1.题目要求
    • 2.解题思路
    • 3.代码
    • 4.运行结果
  • 二、PA1 option
    • 1.题目要求
    • 2.解题思路
    • 3.代码
    • 4.运行结果
  • 三、cryptopals set 1
    • 1.题目要求
    • 2.解题思路
    • 3.代码
    • 4.运行结果
  • 四、MTC3 SHA1-Hashed Passwords:
    • 1.题目要求
    • 2.解题思路
    • 3.代码
    • 4.运行结果
  • 总结

前言

本次作业共4个题目,分别为Week1 PA、PA1 option、cryptopals set 1、MTC3 SHA1-Hashed Passwords


一、Week1 PA

1.题目要求

Many Time Pad
让我们看看当一个流密码密钥被使用多次时会出现什么问题。下面是11个十六进制编码的密文,它们是用流密码对11个明文进行加密的结果,它们都使用相同的流密码密钥。您的目标是解密最后的密文,并将其中的秘密消息作为解决方案提交。
11个密文具体内容可在题目页看到。

2.解题思路

1.流加密的加密算法核心是按位异或操作,而如果要解密数据,只需要将密文与密钥串进行按位异或,即可得到原数据。
假设A、B两串明文数据,key为加密数据A、B所使用的密钥。加密后的数据A用EA表示(EA = A ⊕ key),加密后的数据B用EB表示(EB = B ⊕ key),符号⊕表示异或操作。
利用相同的值异或结果为0可以得出:
EA ⊕ EB = (A ⊕ key)⊕ (B ⊕ key)= A ⊕ B ⊕ (key ⊕ key)= A ⊕ B
此时只要知道任一明文串就可以对所有的明文串解密:
EA ⊕ EB ⊕ B = A ⊕ B ⊕ B = A
2.在ASCII表中,空格的16进制数0x20,字母A-Z的16进制数范围是0x41-0x5A,a-z的16进制数范围是0x61-0x7A,按位异或可以发现,一个大写字母与空格异或可以得到对应的小写字母;一个小写字母与空格异或可以得到对应大写字母。
3.基于以上两种特点,我们可以对11个密文两两做异或操作,判断不同明文中可能存在空格的位置,
EA ⊕ EB = (A ⊕key)⊕ (B ⊕ key)= A ⊕ B ⊕ (key ⊕ key)= A ⊕ B
当获取足够多的位置信息后,将对应位置上的密文和空格做异或操作,就可得到对应位置的密钥信息

3.代码

代码如下:

#密文为十六进制字符串,应该先将其处理
ciphertexts = ["315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e","234c02ecbbfbafa3ed18510abd11fa724fcda2018a1a8342cf064bbde548b12b07df44ba7191d9606ef4081ffde5ad46a5069d9f7f543bedb9c861bf29c7e205132eda9382b0bc2c5c4b45f919cf3a9f1cb74151f6d551f4480c82b2cb24cc5b028aa76eb7b4ab24171ab3cdadb8356f","32510ba9a7b2bba9b8005d43a304b5714cc0bb0c8a34884dd91304b8ad40b62b07df44ba6e9d8a2368e51d04e0e7b207b70b9b8261112bacb6c866a232dfe257527dc29398f5f3251a0d47e503c66e935de81230b59b7afb5f41afa8d661cb","32510ba9aab2a8a4fd06414fb517b5605cc0aa0dc91a8908c2064ba8ad5ea06a029056f47a8ad3306ef5021eafe1ac01a81197847a5c68a1b78769a37bc8f4575432c198ccb4ef63590256e305cd3a9544ee4160ead45aef520489e7da7d835402bca670bda8eb775200b8dabbba246b130f040d8ec6447e2c767f3d30ed81ea2e4c1404e1315a1010e7229be6636aaa","3f561ba9adb4b6ebec54424ba317b564418fac0dd35f8c08d31a1fe9e24fe56808c213f17c81d9607cee021dafe1e001b21ade877a5e68bea88d61b93ac5ee0d562e8e9582f5ef375f0a4ae20ed86e935de81230b59b73fb4302cd95d770c65b40aaa065f2a5e33a5a0bb5dcaba43722130f042f8ec85b7c2070","32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd2061bbde24eb76a19d84aba34d8de287be84d07e7e9a30ee714979c7e1123a8bd9822a33ecaf512472e8e8f8db3f9635c1949e640c621854eba0d79eccf52ff111284b4cc61d11902aebc66f2b2e436434eacc0aba938220b084800c2ca4e693522643573b2c4ce35050b0cf774201f0fe52ac9f26d71b6cf61a711cc229f77ace7aa88a2f19983122b11be87a59c355d25f8e4","32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5ba47b01c909ba764896cf606ef40c04afe1ac0aa81dd066592ded9f8774b529c7ea125d298e8883f5e9305f4b44f915cb2bd05af51373fd9b4af511039fa2d96f83414aaaf261bda2e97b170fb5cce2a53e675c154c0d9681596934777e2275b381ce2e40582afe67650b13e72287ff2270abcf73bb028932836fbdecfecee0a3b894473c1bbeb6b4913a536ce4f9b13f1efff71ea313c8661dd9a4ce","315c4eeaa8b5f8bffd11155ea506b56041c6a00c8a08854dd21a4bbde54ce56801d943ba708b8a3574f40c00fff9e00fa1439fd0654327a3bfc860b92f89ee04132ecb9298f5fd2d5e4b45e40ecc3b9d59e9417df7c95bba410e9aa2ca24c5474da2f276baa3ac325918b2daada43d6712150441c2e04f6565517f317da9d3","271946f9bbb2aeadec111841a81abc300ecaa01bd8069d5cc91005e9fe4aad6e04d513e96d99de2569bc5e50eeeca709b50a8a987f4264edb6896fb537d0a716132ddc938fb0f836480e06ed0fcd6e9759f40462f9cf57f4564186a2c1778f1543efa270bda5e933421cbe88a4a52222190f471e9bd15f652b653b7071aec59a2705081ffe72651d08f822c9ed6d76e48b63ab15d0208573a7eef027","466d06ece998b7a2fb1d464fed2ced7641ddaa3cc31c9941cf110abbf409ed39598005b3399ccfafb61d0315fca0a314be138a9f32503bedac8067f03adbf3575c3b8edc9ba7f537530541ab0f9f3cd04ff50d66f1d559ba520e89a2cb2a83","32510ba9babebbbefd001547a810e67149caee11d945cd7fc81a05e9f85aac650e9052ba6a8cd8257bf14d13e6f0a803b54fde9e77472dbff89d71b57bddef121336cb85ccb8f3315f4b52e301d16e9f52f904"
]NUM_CIPHER = len(ciphertexts)#NUM_CIPHER=11
THRESHOLD_VALUE = 7#如果两两异或的结果为字母数大于7次,就认为该字符为空格,该值更改会影响最终结果def strxor(a, b):#两个字符串的异或if len(a) > len(b):# 形成二元组,异或,返回新字符串return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])else:return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])def letter_position(s):#返回给定字符串中给定字母的位置position = []for idx in range(len(s)):#考虑到空格异或为0的情况可能较多if (s[idx] >= 'A' and s[idx] <= 'Z') or (s[idx] >= 'a' and s[idx] <= 'z') or s[idx] == chr(0):position.append(idx)return positiondef find_space(cipher):#寻找空字符space_position = {}space_possible = {}#双重循环,每一条密文均与其他密文异或for cipher_idx_1 in range(NUM_CIPHER):space_xor = []#用于保存可能空格符对应的位置c = ''.join([chr(int(d, 16)) for d in [cipher[cipher_idx_1][i:i + 2] for i in range(0, len(cipher[cipher_idx_1]), 2)]])for cipher_idx_2 in range(NUM_CIPHER):#将十六进制字符串处理成对应ascii字符(每两个字符代表一个ascii符号)e = ''.join([chr(int(d, 16)) for d in [cipher[cipher_idx_2][i:i+2] for i in range(0, len(cipher[cipher_idx_2]), 2)]])plain_xor = strxor(c, e)if cipher_idx_2 != cipher_idx_1:# 记录明文中可能空格符的位置space_xor.append(letter_position(plain_xor))space_possible[cipher_idx_1] = space_xor  #形成三维列表,新列表为11*10*n#进一步判断已记录的位置是否为空字符,其准确性受到文本数量的影响for cipher_idx_1 in range(NUM_CIPHER):spa = []for position in range(400):count = 0for cipher_idx_2 in range(NUM_CIPHER - 1):if position in space_possible[cipher_idx_1][cipher_idx_2]:count += 1if count > THRESHOLD_VALUE:  # 如果异或后字母出现次数大于7次,认为明文中此处为空格spa.append(position)space_position[cipher_idx_1] = spa  #构成二维列表,11 * nreturn space_position#计算获得对应密钥Key
def calculate_key(cipher):key = [0] * 200  #存放keyspace = find_space(cipher)#print(space)for cipher_idx_1 in range(NUM_CIPHER):for position in range(len(space[cipher_idx_1])):idx = space[cipher_idx_1][position] * 2 #十六进制,用2位表示a = cipher[cipher_idx_1][idx] + cipher[cipher_idx_1][idx + 1]key[space[cipher_idx_1][position]] = int(a ,16) ^ ord(' ') # 计算密钥,获得结果十进制(ascii码)key_str = ""#空串用于存放密钥for k in key:key_str += chr(k)#转化为return key_str  #获得密钥串result = ""
key = calculate_key(ciphertexts)
key_hex = ''.join([hex(ord(c)).replace('0x', '') for c in key])#十六进制key
print("key=",key)
print("key_hex=",key_hex)f = ''.join([chr(int(d, 16)) for d in [ciphertexts[10][i:i+2] for i in range(0, len(ciphertexts[10]), 2)]])
for letter in strxor(f,key):if (letter>=' ' and letter<='~ '):#打印从32-126的可见字符result+=letterelse:result+='0'#不可打印字符用0代替,以区别空格符
print(result)#打印所有密文对应的明文
for j in range(11):f = ''.join([chr(int(d, 16)) for d in [ciphertexts[j][i:i + 2] for i in range(0, len(ciphertexts[j]), 2)]])for letter in strxor(f,key):if (letter>=' ' and letter<='~ '):result+=letterelse:result+='0'print(result)result = '' #将result清空,再次使用

4.运行结果


二、PA1 option

1.题目要求

Write a program that allows you to “crack” ciphertexts generated using a Vigenere-like cipher, where byte-wise XOR is used instead of addition modulo 26.
编写一个程序, 破解使用类似Vigenere密码加密的密文,其中使用逐字节的异或而不是模26加法。

Ciphertext:
F96DE8C227A259C87EE1DA2AED57C93FE5DA36ED4EC87EF2C63AAE5B9A7EFFD673BE4ACF7BE8923CAB1ECE7AF2DA3DA44FCF7AE29235A24C963FF0DF3CA3599A70E5DA36BF1ECE77F8DC34BE129A6CF4D126BF5B9A7CFEDF3EB850D37CF0C63AA2509A76FF9227A55B9A6FE3D720A850D97AB1DD35ED5FCE6BF0D138A84CC931B1F121B44ECE70F6C032BD56C33FF9D320ED5CDF7AFF9226BE5BDE3FF7DD21ED56CF71F5C036A94D963FF8D473A351CE3FE5DA3CB84DDB71F5C17FED51DC3FE8D732BF4D963FF3C727ED4AC87EF5DB27A451D47EFD9230BF47CA6BFEC12ABE4ADF72E29224A84CDF3FF5D720A459D47AF59232A35A9A7AE7D33FB85FCE7AF5923AA31EDB3FF7D33ABF52C33FF0D673A551D93FFCD33DA35BC831B1F43CBF1EDF67F0DF23A15B963FE5DA36ED68D378F4DC36BF5B9A7AFFD121B44ECE76FEDC73BE5DD27AFCD773BA5FC93FE5DA3CB859D26BB1C63CED5CDF3FE2D730B84CDF3FF7DD21ED5ADF7CF0D636BE1EDB79E5D721ED57CE3FE6D320ED57D469F4DC27A85A963FF3C727ED49DF3FFFDD24ED55D470E69E73AC50DE3FE5DA3ABE1EDF67F4C030A44DDF3FF5D73EA250C96BE3D327A84D963FE5DA32B91ED36BB1D132A31ED87AB1D021A255DF71B1C436BF479A7AF0C13AA14794

2.解题思路

1.枚举密钥长度(从1到13)
2.将十六进制解码后的密文按密钥长度分块,取出每一块中的第一个字符作为第一组,取出每块中的第二个字符作为第二组,以次类推。
(根据Vigenere加密的特点可以知道,第一组中的字符是由密钥的第一个字符加密得到的,第二组中的字符是由密钥的第二个字符加密得到的……)
3.从0-255穷举当前密钥长度下密钥中的每一个字符,例如:将这个字符与第一组的字符依次异或,直到异或出来的结果都是大小写字母、标点符号和空格,记录这个字符,作为密钥的第一个字符,以此类推去穷举第二个、第三个字符……
4.如果在当前密钥长度下,能找出满足明文要求的密钥的所有字符,则可能找到了正确的密钥长度和密钥。若找不全密钥的所有字符,则说明当前密钥长度错误,将密钥长度加一,再次返回第2步。
5.用密钥与密文异或解密出原文

3.代码

代码如下:

import string# 使用穷举密钥法
# 1.选择密钥长度
# 2.确定密钥中每个字符的值(0x00-0xFF)
ciphertext = 'F96DE8C227A259C87EE1DA2AED57C93FE5DA36ED4EC87EF2C63AAE5B9A\
7EFFD673BE4ACF7BE8923CAB1ECE7AF2DA3DA44FCF7AE29235A24C963FF0DF3CA3599A\
70E5DA36BF1ECE77F8DC34BE129A6CF4D126BF5B9A7CFEDF3EB850D37CF0C63AA2509A\
76FF9227A55B9A6FE3D720A850D97AB1DD35ED5FCE6BF0D138A84CC931B1F121B44ECE\
70F6C032BD56C33FF9D320ED5CDF7AFF9226BE5BDE3FF7DD21ED56CF71F5C036A94D96\
3FF8D473A351CE3FE5DA3CB84DDB71F5C17FED51DC3FE8D732BF4D963FF3C727ED4AC8\
7EF5DB27A451D47EFD9230BF47CA6BFEC12ABE4ADF72E29224A84CDF3FF5D720A459D4\
7AF59232A35A9A7AE7D33FB85FCE7AF5923AA31EDB3FF7D33ABF52C33FF0D673A551D9\
3FFCD33DA35BC831B1F43CBF1EDF67F0DF23A15B963FE5DA36ED68D378F4DC36BF5B9A\
7AFFD121B44ECE76FEDC73BE5DD27AFCD773BA5FC93FE5DA3CB859D26BB1C63CED5CDF\
3FE2D730B84CDF3FF7DD21ED5ADF7CF0D636BE1EDB79E5D721ED57CE3FE6D320ED57D4\
69F4DC27A85A963FF3C727ED49DF3FFFDD24ED55D470E69E73AC50DE3FE5DA3ABE1EDF\
67F4C030A44DDF3FF5D73EA250C96BE3D327A84D963FE5DA32B91ED36BB1D132A31ED8\
7AB1D021A255DF71B1C436BF479A7AF0C13AA14794'# 密文为16进制编码 密文中两个十六进制数对应一个字符
def hexDecode(text):cList = []for i in range(0, len(text), 2):cList.append(int(text[i:2 + i], 16))return cList# 从0x00-0xFF验证每一位密钥
def keyfind(strGroup):# 由题目得知明文中包含大小写字母、标点符号和空格,但不包含数字possibleChars = string.ascii_letters + ',' + '.' + ' 'testKeys = []trueKeys = []for i in range(0x00, 0xFF):testKeys.append(i)trueKeys.append(i)for i in testKeys:for j in strGroup:if chr(i ^ j) not in possibleChars:trueKeys.remove(i)breakreturn trueKeys# 密文中两个十六进制数对应一个字符
cipherList = hexDecode(ciphertext)
# 枚举密钥长度从1-13位
trueKeylen = 0
truevigenerekey = []
for keyLen in range(1, 14):vigenerelikeKey = []for i in range(0, keyLen):# 每隔一个keyLen取一个字符保存在strGroup中,strGroup中的所有字符都是由同一个密钥字符加密的strGroup = cipherList[i::keyLen]ansKeys = keyfind(strGroup)if not ansKeys:breakelse:vigenerelikeKey.insert(i, ansKeys)if vigenerelikeKey:trueKeylen = keyLentruevigenerekey = vigenerelikeKeyprint('枚举出的密钥长度为', keyLen)print('密钥为(十进制ASCII码表示)', vigenerelikeKey)# 用密钥解密密文
plaintext = ''
for i in range(0, len(cipherList)):plaintext = plaintext + chr(cipherList[i] ^ truevigenerekey[i % trueKeylen][0])
print('解密后的明文为', plaintext)

4.运行结果


三、cryptopals set 1

1.题目要求

给出了一个文件,该文件首先经过repeating-key XOR,然后base64编码得到。要求我们给出密钥和明文。
文件内容如下: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

2.解题思路

题目中给出了提示:
1.确定KEYSIZE,也就是密钥的长度,比如说可以尝试从2到40的值
2.实现一个函数,该函数功能是计算两个字符串的汉明距
3.每次尝试KEYSIZE时,分别计算两个长度为KEYSIZE的字节的串,计算其汉明距
4.选取2-3个最小汉明距离的KEYSIZE(如果选取了正确的密钥长度,两两块之间的汉明距离的值应该趋于小),在确定时可以采用一些技巧,如选取4个块,两两组合计算汉明距,再除以组合数,再除以key_size,进行规格化。
5.知道KEYSIZE大小后,将密文按照KEYSIZE大小分到每个块里面
6.然后可以重新组合,将每个块的第一个字节取出来重新组成一个块,将每个块的第二个字节取出来重新组成第二个块。。
7.对于新组成的块而言,此时解密就相当于是单字符的异或,我们之前已经学过怎么处理这种情况了
8.将每个单字符异或的key组合起来就是我们要求的repeating-key XOR的key了,将明文拼接起来就是所求的完整明文了

3.代码

代码如下:

import base64
import itertools# 字母频率表
charfreq = {'a': 0.0651738, 'b': 0.0124248, 'c': 0.0217339,'d': 0.0349835, 'e': 0.1041442, 'f': 0.0197881,'g': 0.0158610, 'h': 0.0492888, 'i': 0.0558094,'j': 0.0009033, 'k': 0.0050529, 'l': 0.0331490,'m': 0.0202124, 'n': 0.0564513, 'o': 0.0596302,'p': 0.0137645, 'q': 0.0008606, 'r': 0.0497563,'s': 0.0515760, 't': 0.0729357, 'u': 0.0225134,'v': 0.0082903, 'w': 0.0171272, 'x': 0.0013692,'y': 0.0145984, 'z': 0.0007836, ' ': 0.1918182
}# 计算文本的分值:该分值是所有在输入字符串中出现的字符对应在字符频率表中的频率相加
def engScore(tbytes):score = 0for byte in tbytes:score += charfreq.get(chr(byte).lower(), 0)return score# 字符串与密钥(同一个)异或函数
def charXor(tbytes, keyvalue):output = b''for char in tbytes:output += bytes([char ^ keyvalue])return output# 密钥从0-255暴力破解函数
def singlecharXor(ciphertext):candidates = []for keyCandidates in range(256):plainCandidates = charXor(ciphertext, keyCandidates)candidateScore = engScore(plainCandidates)result = {'key': keyCandidates,'score': candidateScore,'plaintext': plainCandidates}candidates.append(result)return sorted(candidates, key=lambda c: c['score'], reverse=True)[0]# 字符串与重复密钥异或函数
def repeatkeyXor(tbytes, key):output = b''i = 0for byte in tbytes:output += bytes([byte ^ key[i]])i = i + 1 if i < len(key) - 1 else 0return output# 计算两个字符串的hamming距离
def hammingDistance(str1, str2):assert len(str1) == len(str2)dist = 0for x, y in zip(str1, str2):b = x ^ y  # 转换为二进制(以字符串形式表示,如“0b100000”,0b表示二进制)dist += sum([1 for bit in bin(b) if bit == '1'])return distdef breakrepeatingkeyXor(binarydata):normalizedDistances = {}for keySize in range(2, 41):# 取出根据keySize划分出的4组数据group = [binarydata[i:i + keySize] for i in range(0, len(binarydata), keySize)][:4]distance = 0# 使用迭代器itertools中的combinations对4组中进行两两任意组合pairs = itertools.combinations(group, 2)for (x, y) in pairs:distance += hammingDistance(x, y)distance /= 6normalizedDistance = distance / keySizenormalizedDistances[keySize] = normalizedDistancepossiblekeySizes = sorted(normalizedDistances, key=normalizedDistances.get)[:3]print(possiblekeySizes)possiblePlaintexts = []for d in possiblekeySizes:key = b''for i in range(d):block = b''for j in range(i, len(binarydata), d):block += bytes([binarydata[j]])key += bytes([singlecharXor(block)['key']])possiblePlaintexts.append((repeatkeyXor(binarydata, key), key))return max(possiblePlaintexts, key=lambda k: engScore(k[0]))def main():with open("ctext.txt") as fp:data = base64.b64decode(fp.read())result = breakrepeatingkeyXor(data)print("key = ", result[1].decode())print("长度= ", len(result[1].decode()))print(result[0].decode().rstrip())if __name__ == "__main__":main()

4.运行结果


四、MTC3 SHA1-Hashed Passwords:

1.题目要求

根据键盘上的密码输入情况来破解密码,密码的hash值为67ae1a64661ac8b4494666f58c4822408dd0a3e4

2.解题思路

根据键盘上的按键分布,可以看出右边的数字键只有2486,很有可能是当做上下左右的功能,然后对剩余的按照每个按键出现1次进行暴力,发现能得出解。

3.代码

代码如下:

import hashlib
import itertools
import datetimestart = datetime.datetime.now()
SHA1hash = "67ae1a64661ac8b4494666f58c4822408dd0a3e4"
testStr = [['Q', 'q'], ['W', 'w'], ['5', '%'], ['8', '('], ['=', '0'], ['I', 'i'], ['*', '+'], ['n', 'N']]def sha1Encrypt(str):sha = hashlib.sha1(str.encode())encrypts = sha.hexdigest()return encrypts#按照每个键按了一次进行暴力破解
liststr = "0" * 8
tempstr = ""
testPassword = list(liststr)
for a in range(0, 2):testPassword[0] = testStr[0][a]for b in range(0, 2):testPassword[1] = testStr[1][b]for c in range(0, 2):testPassword[2] = testStr[2][c]for d in range(0, 2):testPassword[3] = testStr[3][d]for e in range(0, 2):testPassword[4] = testStr[4][e]for f in range(0, 2):testPassword[5] = testStr[5][f]for g in range(0, 2):testPassword[6] = testStr[6][g]for h in range(0, 2):testPassword[7] = testStr[7][h]temp = "".join(testPassword)for i in itertools.permutations(temp, 8):tempPw="".join(i)tempstr = sha1Encrypt(tempPw)if tempstr == SHA1hash:print("密码为:",tempPw)end = datetime.datetime.now()print("运行时间为:",end - start)exit(0)

4.运行结果


总结

通过这次实验学习了很多与流密码相关的攻击方式,当我们实际需要应用到流密码时,不应该自己去实现,而是直接使用库中的流密码。

Cryptography Assignment(Ⅰ)相关推荐

  1. Cryptography Assignment(Ⅲ)

    文章目录 前言 一.题目描述 二.解题过程 1.提取N.e.c 2.Frame3.Frame8.Frame12.Frame16.Frame20 3.Frame7.Frame11.Frame15 4.F ...

  2. 关于Ilegal assignment(Quart II)问题的解决

    Ilegal assignment(Quart II)问题的解决 1.问题来源 大概率来自复制别人工程文件时,进行编译所出现的问题,可能是版本号以及IP名称的改变所引起的. 常见与上述错误. 2.问题 ...

  3. 西电新时代网信院特色通信原理Assignment(自用)

    CHAP-1 (单选题, 10分)数字通信相对于模拟通信具有( )的优点 A. 占用频带小 B. 抗干扰能力强 C. 传输容量大 D. 易于频分复用 正确答案: B (单选题, 10分)M进制的离散消 ...

  4. 如何使用基于范围的for()循环与std :: map?

    本文翻译自:How to use range-based for() loop with std::map? The common example for C++11 range-based for( ...

  5. init()函数何时运行?

    本文翻译自:When is the init() function run? I've tried to find a precise explanation of what the init() f ...

  6. python bytes_Python bytes()

    python bytes Python bytes() is a built-in function. This function returns bytes object that is an im ...

  7. R语言入门之——箭头(<-)与等于号(=)的区别

    目录 0引言 1.历史来源 2.<- 和=的区别案例 2.1 = or <- :函数传参 3.总结与扩展 0引言 对于R语言的初学者,往往会遇到<-和=这两个赋值符号,本文本主要用箭 ...

  8. JS 特性:可选链(?.)

    可选链操作符 参考文献: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Optional_ch ...

  9. python 替换字符串的方法replace()、正则re.sub()

    一.replace()函数 1用字符串本身的replace方法: a = 'hello word' b = a.replace('word','python') print b 1 2 3 二.re. ...

最新文章

  1. WEBSHELL恶意代码批量提取清除工具
  2. Sql Server 因为触发器问题导致数据库更新报错“在触发器执行过程中引发了错误,批处理已中止”的问题处理...
  3. 设置cisco登录时显示的警示性信息-banner
  4. iOS系统 应用闪退或图标消失的解决办法
  5. Angular jasmine单元测试框架里spyOn的创建原理
  6. Spring DAO之JDBC
  7. oracle 高级dba,DAVE老师Oracle DBA高级运维深入解析实战班 高级DBA运维视频 Oracle视频教程...
  8. 海康—SADP激活(设备网络搜索)
  9. 墨者mysql注入_墨者靶场:SQL注入漏洞测试(参数加密) 使用sqlmap进行注入
  10. Oracle字符串操作[转:http://www.cnblogs.com/xd502djj/archive/2010/08/11/1797577.html]
  11. vulcan测试记录
  12. android获取全部ram和rom,ROM与RAM的那点事,超详细解说
  13. 软件测试 | 测试开发 | Git实战(四)| Git分支管理实操,在线合并和本地合并
  14. Opencv3学习笔记(C++Python双语)---视屏读取与保存
  15. Flutter桌面开发 - windows插件开发
  16. vue-cil创建vue项目
  17. 分道扬镳 /// 邻接表 DFS 剪枝 oj1332
  18. Python调用Gurobi求解简单线性规划问题
  19. Word Embedding的通俗解释
  20. as3corelib 的 MD5.digest.endian 应该是 LITTLE_ENDIAN

热门文章

  1. css零到一基础教程044:CSS 图标
  2. 聚类分析经典算法(一)
  3. Win10下Delphi 10.4.2 (RAD Studio 10.4.2 )安装教程图解
  4. Vue移动端UI框架mux-ui
  5. 【星辰傀儡线·命运环·卷一 血鸦】 6 四大长老
  6. 留一法(Leave-One-Out)与确定性
  7. Redis进阶学习--02| AOF日志:宕机了,Redis如何避免数据丢失?
  8. 如何减轻 Smurf 攻击?
  9. mybatis日志打印大杀器
  10. python 获取字符串MD5值