超强鉴别 cdn 小工具

news2024/10/6 10:47:42

最近做一个攻防演习,使用了一些工具收集域名,子域名,但是在将这些域名解析成 IP 这个过程遇到了一些小问题,默认工具给出的 cdn 标志根本不准,所以被迫写了这么一个小工具:get_real_ip.py

PS:下面有详细代码,文章最后有下载链接

使用方法

  • 安装依赖包 pip3 install -r requirements.txt

  • 将要检测的域名放入到文件中,假设文件为 domains.txt

  • 假设设置线程为 20 (默认为 50)

  • 执行 python3 get_real_ip.py -f domains.txt

图片

使用了 cdn 的域名放到了文件 domain_with_cdn_xxxx 中,未使用 cdn 的域名解析的 IP 放到了real_ip_xxxx  中

注意事项

  • 执行后,如果目标没有使用cdn,你是会向目标发起至少两次无害的 web 请求的,如果不想暴漏IP,就做好准备

  • 建议选择可以解析目标域名的 DNS 服务器来测试,脚本自带的都是效果比较好的,自己选择的话下文有说

  • 移动的 DNS 服务器是不支持其他运营商网络使用的,如果你不是移动的网络,而且要追求那一丢丢可能出现的遗漏,可以考虑在移动网络下再执行一次

脚本中的一些技术点

判定方法

判定方法很简单,使用了全球各地的 DNS 服务器对域名的 A 记录进行解析,之后根据结果 IP 数量来进行判断,这里选择的阈值是 3,这也对应着三大运营商,解析得到不同的 ip 数量大于 3 个就认为使用了 cdn

为了加速判定,这里先选择了具有代表性的四个 DNS 服务器,对某个域名的 A 记录进行解析,如果得到的结果 IP数量大于 3 个,那么就认为其使用了 cdn。如果小于 4 个,对其进行 web 网页标题检查,将直接 IP 访问网页标题一致的保存下来,如果存在不一致的,那么就进行常规检查

常规检查就是通过精心选择的大量 DNS 服务器对该域名进行 A 记录解析,再根据 IP 数量进行判定,阈值依旧是 3

DNS 服务器的选择

一开始我们选择了非常多的 DNS 服务器,遍布全球,但后来经过不断测试发现,很多 DNS 服务器对国内域名的解析并不友好,最后保留了近 50 个 DNS 服务器

选择 DNS 服务器至少包括:

  • 国内外常用的公共 DNS 服务器

  • 中国大陆南方DNS服务器、中国大陆北方DNS服务器

  • 香港、台湾、澳门地区的 DNS 服务器

  • 美国、日本、俄罗斯、澳大利亚、德国、加拿大、法国、泰国的DNS服务器

  • 国内三大运营商的 DNS 服务器

运营商 DNS 困境

假如这次测试的目标是百度,那么就使用这些DNS服务器先解析一下 www.baidu.com 试一下

寻找其他 DNS 服务器的时候,问题其实不是很大,使用这些 DNS 服务器解析一下的 www.baidu.com 就行了,如果有结果,没有报错,又符合条件,那就可以加入进来,但是到了运营商这里,问题就来了

运营商的 DNS 非常多,每个省都有,但是这些 DNS 中绝大多数都有地域限制,比如说你是山西的联通网络,那么你就只能使用山西的联通 DNS,而不能使用其他地区的联通 DNS,也不能使用其他运营商的 DNS

我们耗费了很长时间,终于找到了允许任意运营商、任意地区的网络使用的联通和电信的 DNS 服务器,移动的并没有找到,DNS服务器这么多,如果一个一个测试,那实在是太折磨人了,于是有了下面的部分

自定义 DNS 服务器列表

因为 DNS 数量太多了,不知道具体哪些 DNS 服务器能够成功解析当前目标的比较有代表性的域名,所以我们拿出了祖传技能,写了一个 Nmap 的 NSE 脚本 find-useful-dnsserver.nse 来帮助我们批量测试

local dns = require "dns"
local nmap = require "nmap"
local stdnse = require "stdnse"


description = [[ Attempts to test if these dns servers are available. ]]

-- 2022-05-20
---
-- @usage
-- sudo nmap --script find-useful-dnsserver.nse --script-args dns-query.domain=www.baidu.com -sU -p 53 -iL dns_servers.txt -Pn 
-- @args dns-brute.domain   The domain to test dns servers. Defaults to "www.baidu.com"
--
-- @output
-- PORT   STATE SERVICE
-- 53/udp open  domain

-- Host script results:
-- | find-useful-dnsserver: 
-- |   result: Successfully resolved: www.baidu.com
-- |_  mymark_dns_ip: 8.8.8.8
--



author = "test94"

license = "Same as Nmap--See https://nmap.org/book/man-legal.html"

categories = {"intrusive", "discovery"}

prerule = function()
  if not stdnse.get_script_args("dns-query.domain") then
    stdnse.debug1("please input the domain to test.")
    return false
  end
end

hostrule = function()
  return true
end

action = function(host)
  local domainname = stdnse.get_script_args('dns-query.domain')

  -- 如果没有指定域名,那就用 www.baidu.com 来进行测试
  if not domainname then
    domainname = "www.baidu.com"
  end

  local status, result = dns.query(domainname, {dtype="A",retAll=true,host=host.ip})
  local output = stdnse.output_table()

  if status then
    output.result = "Successfully resolved: " .. domainname
    output.mymark_dns_ip = host.ip
    
  else
    output.result = "Failed to resolve: " .. domainname
  end
  return output
end

具体使用方法如下:

  • 将要测试的 DNS 服务器地址写入到文件中,这里以 dns_servers.txt 为例

  • 将当前路径切换到脚本所在的路径下

  • 假设目标为 www.baidu.com

  • 执行 sudo nmap --script find-useful-dnsserver.nse --script-args dns-query.domain=www.baidu.com -iL dns_servers.txt -sU -p53 -oN result.txt -Pn

  • 如果脚本发现了可用的 DNS 服务器,result.txt 中会有 mark 标记,筛选就可以了

  • 筛选 cat result.txt | grep mark | cut -d " " -f 4

图片

图片

这些 DNS 地址就是有效 DNS 服务器地址了,用它们来测试准没错

【已更新,从下面的百度云链接下载】最后附上 get_real_ip.py 的代码:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Author: 意大利的猫

'''
    这个程序用来将使用了 cdn 和没有使用 cdn 的域名分开,获取没有使用 cdn 的域名的真实 ip

'''

import datetime
import argparse
import requests
from bs4 import BeautifulSoup
import time
import threading
import queue
import dns.resolver
import sys
import re
import tldextract

# pip3 freeze > requirements.txt 生成 requirements.txt


# 函数时间装饰器
def functime(func):
    def wap(*args, **kw):
        local_time = datetime.datetime.now()
        func(*args, **kw)
        times = (datetime.datetime.now() - local_time).seconds
        print('Run time is {} minutes {} seconds'.format(
            times // 60, times % 60))

    return wap


# 类方法时间装饰器
# def get_class_func_time(func):
#     def wrapper(self, *args, **kwargs):
#         local_time = datetime.datetime.now()
#         func(self, *args, **kwargs)
#         times = (datetime.datetime.now() - local_time).seconds
#         funcname = func.__name__
#         print('Run {} time is {} minutes {} seconds'.format(
#             funcname, times // 60, times % 60))
#     return wrapper


class GetRealIP:
    """ 
    =================================================
    功能: 这个类用来获取域名的真实IP
    args:
        domain_file, 域名列表文件
        threads, 线程数
    =================================================

    """

    # 构造函数
    def __init__(self, domain_file, threads):
        self.domain_file = domain_file
        self.threads = threads
        self.thread_list = []
        self.ip_list = []
        self.cdn_domains_list = []
        self.myResolver = dns.resolver.Resolver()
        self.myResolver.retry_servfail = True
        self.myResolver.timeout = 3
        self.lock = threading.Lock()
        self.DOMAIN_QUEUE = queue.Queue()

        nowTime = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
        self.save_ip_file = "real_ip_" + str(nowTime) + ".txt"
        self.save_cdn_domain_file = "domain_with_cdn_" + str(nowTime) + ".txt"
        self.fast_nameservers = ["114.114.114.114", "8.8.8.8", "223.5.5.5", "80.80.80.80"]
        self.nameservers = ['8.8.4.4',
               '8.8.8.8',
               '114.114.114.114',
               '1.1.1.1',
               '119.29.29.29',
               '223.5.5.5',
               '180.76.76.76',
               '117.50.10.10',
               '208.67.222.222',
               '223.6.6.6',
               '4.2.2.1',
               '168.95.1.1',
               '202.14.67.4',
               '202.14.67.14',
               '168.95.192.1',
               '168.95.1.1',
               '202.86.191.50',
               '202.175.45.2',
               '202.248.20.133',
               '211.129.155.175',
               '101.110.50.105',
               '212.66.129.108',
               '104.152.211.99',
               '9.9.9.9',
               '82.127.173.122',
               '61.19.42.5',
               '210.23.129.34',
               '210.80.58.3',
               '62.122.101.59',
               '80.66.158.118',
               '101.226.4.6',
               '218.30.118.6',
               '123.125.81.6',
               '140.207.198.6',
               '80.80.80.80',
               '61.132.163.68',
               '202.102.213.68',
               '202.98.192.67',
               '202.98.198.167',
               '210.22.70.3',
               '123.123.123.123',
               '210.22.84.3',
               '221.7.1.20',
               '221.7.1.21',
               '202.116.128.1',
               '202.192.18.1', 
               '211.136.112.50', 
               '211.138.30.66']
        
        

    """ 
    =================================================
    功能:批量做 dns 解析的函数
    参数:
        domain              待解析的域名
        nameservers_list    用来解析域名的 dns 服务器地址

    返回值:
        result_list         解析这个域名得到的 IP 列表
    ==================================================
    """
    
    def dns_resolve(self, domain, nameservers_list):
        local_Resolver = dns.resolver.Resolver()
        local_Resolver.retry_servfail = True
        local_Resolver.timeout = 3
        result_list = []

        for name_server in nameservers_list:
            # time.sleep(1)
            local_Resolver.nameservers = [name_server]
            if len(result_list) > 4:
                return result_list

            try:
                myAnswers = local_Resolver.resolve(domain, "A", lifetime=1)

                for rdata in myAnswers:
                    if rdata.address not in result_list and ":" not in rdata.address:# and len(result_list) < 5:
                        result_list.append(rdata.address)
                
            except Exception as error:
                continue

        return result_list


    ''' 
    =================================================
    功能: 获取网页编码,循环获取,非常变态
    参数:
        soup              bs4 的 返回值

    返回值:
        encoding          返回页面编码
    =================================================
    '''
    def get_encoding(self, soup):
        encoding = None
        if soup:
            for meta_tag in soup.find_all("meta"):
                encoding = meta_tag.get('charset')
                if encoding: break
                else:
                    encoding = meta_tag.get('content-type')
                    if encoding: break
                    else:
                        content = meta_tag.get('content')
                        if content:
                            match = re.search('charset=(.*)', content)
                            if match:
                                encoding = match.group(1)
                                break
        if encoding:
            return str(encoding).lower()
        
        return encoding

    '''
    =================================================
    功能: 这个函数用来解析网页 title 
    参数:
        resp              requests 的返回值

    返回值:
        title.string      网页 title 字符串
    =================================================

    '''
    def parse_title(self, resp):        
        soup_for_charset = BeautifulSoup(resp.text, 'lxml')
        resp.encoding = self.get_encoding(soup_for_charset) or "utf-8"
        soup = BeautifulSoup(resp.text, 'html.parser')
        title = soup.find('title')
        return title.string


    '''
    ========================================================================================     
    功能: 获取使用http 或者 https 协议访问网页,获取网页的 title 
    参数:
        host              domain 或者 ip,通用

    返回值:
        http_title        http 访问得到的 title 
        https_title       https 访问得到的 title
        status_flag       如果 http和https 都无法访问,status_flag = False ,表示 web 访问失败
    ========================================================================================

    '''
    def get_page_title(self, host):
        http_url = "http://" + host + "/"
        https_url = "https://" + host + "/"

        http_title = None
        https_title = None

        status_flag = True

        # 请求头
        Headers = {
            "Upgrade-Insecure-Requests": '1',
            "User-Agent":
                "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0",
            "Connection": "close"
        }

        requests.packages.urllib3.disable_warnings()

        try:
            http_resp = requests.get(http_url, verify=False, headers=Headers, timeout=15, max_retries=3, dely_between_retries=1)
            if http_resp.status_code < 400 or http_resp.status_code == 412:
                http_title = self.parse_title(http_resp)
        except Exception as e:
            pass
            
        try:
            https_resp = requests.get(https_url, verify=False, headers=Headers, timeout=15, max_retries=3, dely_between_retries=1)
            if https_resp.status_code < 400 or https_resp.status_code == 412:
                https_title = self.parse_title(https_resp)
        except Exception as e:
            pass
        
        if http_title == None and https_title == None:
            status_flag = False

        return http_title, https_title, status_flag 

    '''
    ========================================================================================
    功能:用来保存结果 
    参数:
        ip=None           如果是 IP, 那就将其作为真实 IP 进行存储
        cdn_domain=None   如果是域名,那就将其作为使用了cdn 的域名进行存储

    返回值:无返回值
    ========================================================================================
        
    '''
    def save_results(self, ip=None, cdn_domain=None):
        self.lock.acquire()
        if ip and ip not in self.ip_list:
            self.ip_list.append(ip)
            with open(self.save_ip_file, "a+") as f:
                f.write(ip + "\n")

        elif cdn_domain and cdn_domain not in self.cdn_domains_list:
            print(f"[@] {cdn_domain} used cdn ...")
            self.cdn_domains_list.append(cdn_domain)
            with open(self.save_cdn_domain_file, "a+") as f:
                f.write(cdn_domain + "\n")
        self.lock.release()

    '''
    ========================================================================================
    功能:这个函数做常规检查,具体也就是通过几十个 dns 服务器对域名进行解析,根据得到的 ip 数量来判断 
    参数:
        domain           待解析的域名

    返回值:无返回值
    ========================================================================================
        
    '''
    def normal_check(self, domain):
        print(f"[*] normal checking: {domain}")

        normal_list = self.dns_resolve(domain, self.nameservers)
        if 0 < len(normal_list) < 4:
            for ip in normal_list:
                self.save_results(ip=ip)      
        elif len(normal_list) != 0:
            self.save_results(cdn_domain=domain)

    '''
    ========================================================================================
    功能:这个函数做web检查,先用 8.8.8.8 来进行解析,之后使用这个IP直接去访问,
         如果得到的结果和直接用http或者https访问有任何的相同都认为是真实ip 
    参数:
        domain           待测试的域名

    返回值:无返回值
    ========================================================================================
        
    '''
    def web_check(self, domain):
        print(f"[*] web checking: {domain}")

        # 如果 8.8.8.8 解析失败了,那就走常规检查
        ip_list = self.dns_resolve(domain, ["8.8.8.8"])
        if len(ip_list) == 0:
            self.normal_check(domain)
            return

        # 如果用域名访问都获取不到title,那就直接走常规检查
        normal_http_title, normal_https_title, normal_status_flag = self.get_page_title(domain)
        if not normal_status_flag:
            self.normal_check(domain)
            return

        title_list = [normal_http_title, normal_https_title]

        real_ip_flag = 1
        for ip in ip_list:
            ip_http_title, ip_https_title, ip_status_flag = self.get_page_title(ip)

            if ip_status_flag:
                if ip_http_title != None and ip_http_title in title_list:
                    self.save_results(ip=ip)
                elif ip_https_title != None and ip_https_title in title_list:
                    self.save_results(ip=ip)
                else:
                    real_ip_flag = 0

        if not real_ip_flag:
            self.normal_check(domain)

    '''
    ========================================================================================
    功能:这个方法用来快速解析域名,目的是快速去掉一些明显使用了 cdn 的域名
    参数:无参数
    返回值:无返回值
    ========================================================================================
        
    '''
    def fast_check(self):
        # global DOMAIN_QUEUE

        while True: 
            domain = None
            self.lock.acquire()

            if not self.DOMAIN_QUEUE.qsize():
                self.lock.release()
                break

            domain = self.DOMAIN_QUEUE.get()
            self.lock.release()
            print(f"[*] fast checking: {domain}")
           
            fast_list = self.dns_resolve(domain, self.fast_nameservers)
            if 0 < len(fast_list) < 4:
                self.web_check(domain)
            elif len(fast_list) != 0:
                self.save_results(cdn_domain=domain)

    '''
    =======================
    功能:纯属个人爱好
    参数:无参数
    返回值:无返回值
    =======================
        
    '''
    def fire(self):
        print("Fire!!!")
        time.sleep(1)
        # 将域名放入到队列中
        f = self.domain_file
        for domain in f:
            domain = domain.strip()
            self.DOMAIN_QUEUE.put(domain)

        # 创建线程
        for i in range(self.threads):
            t = threading.Thread(target=self.fast_check)
            self.thread_list.append(t)

        # 启动进程
        for t in self.thread_list:
            t.start()

        # 设置子线程结束后才退出程序
        for t in self.thread_list:
            t.join()

'''
    =======================
    功能:主函数
    参数:无参数
    返回值:无返回值
    =======================
        
'''
@functime
def main():
    if args.file:
        domains_file = args.file
        gri = GetRealIP(domain_file=domains_file, threads=args.threads)
        gri.fire()
    else:
        print("Usage: python3 dns_threads.py -f domains.txt --threads=50")


if __name__ == '__main__':
    # 设置各种参数
    parser = argparse.ArgumentParser(description=u'筛选出未使用cdn的域名,并获取真实IP', add_help=False)
    parser.add_argument('-h', '--help', action='help', help=u'显示帮助信息')

    group = parser.add_mutually_exclusive_group()
    group.add_argument('-f', '--file', type=argparse.FileType('r'), help=u'选定要转换的域名文件(按行分割)')
    parser.add_argument('-tn', '--threads', type=int, default=50, help=u'指定线程数,默认50')
    args = parser.parse_args()

    # 调用主函数
    main()


文件下载地址:

https://pan.baidu.com/s/1r2QocjUfAHDSRPMPVEbxhQ 提取码: ah4l

 「你即将失去如下所有学习变强机会」

学习效率低,学不到实战内容,花几千、上万报机构没有性价比

一顿自助钱,我承诺一定让用户满意,也希望用户能给予我一份信任

【详情下方图片了解】,【扫下方二维码加入】:只做高质量优质精品内容」

现在圈子已经有150+师傅相信并选择加入我们,人数满199人将涨价,老用户可永久享受初始加入价格,圈子内容持续更新中

图片

图片

免责声明

由于传播、利用本公众号所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本公众号及作者不为此承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1640262.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ThreeJS:项目搭建

介绍如何基于Vite、Vue、React构建ThreeJS项目。 Vite项目 1. 初始化项目&#xff0c;命令&#xff1a;npm init vitelatest&#xff0c; 2. 安装依赖&#xff0c;命令&#xff1a;npm install&#xff0c; 3. 启动项目&#xff0c;命令&#xff1a;npm run dev。 4. 样式初始…

神经网络中的优化方法

一、引入 在传统的梯度下降优化算法中&#xff0c;如果碰到平缓区域&#xff0c;梯度值较小&#xff0c;参数优化变慢 &#xff0c;遇到鞍点&#xff08;是指在某些方向上梯度为零而在其他方向上梯度非零的点。&#xff09;&#xff0c;梯度为 0&#xff0c;参数无法优化&…

基于Springboot的滑雪场管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的滑雪场管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&a…

【linuxC语言】守护进程

文章目录 前言一、守护进程的介绍二、开启守护进程总结 前言 在Linux系统中&#xff0c;守护进程是在后台运行的进程&#xff0c;通常以服务的形式提供某种功能&#xff0c;如网络服务、系统监控等。守护进程的特点是在启动时脱离终端并且在后台运行&#xff0c;它们通常不与用…

如何使用免费软件从Mac恢复音频文件?

要从Mac中删除任何文件&#xff0c;背后是有原因的。大多数Mac用户都希望增加Mac中的空间&#xff0c;这就是为什么他们更喜欢从驱动器中删除文件以便出现一些空间的原因。一些Mac用户错误地删除了该文件&#xff0c;无法识别这是一个重要文件。例如&#xff0c;他们错误地从Ma…

I/O体系结构和设备驱动程序

I/O体系结构 为了确保计算机能够正常工作&#xff0c;必须提供数据通路&#xff0c;让信息在连接到个人计算机的CPU、RAM和I/O设备之间流动。这些数据通路总称为总线&#xff0c;担当计算机内部主通信通道的作用。 所有计算机都拥有一条系统总线&#xff0c;它连接大部分内部…

ps科研常用操作,制作模式图 扣取想要的内容元素photoshop

复制想要copy的图片&#xff0c; 打开ps---file-----new &#xff0c;ctrolv粘贴图片进入ps 选择魔棒工具&#xff0c;点击想要去除的白色区域 然后&#xff0c;cotrol shift i&#xff0c;反选&#xff0c; ctrol shiftj复制&#xff0c;复制成功之后&#xff0c;一定要改…

【Java EE】Mybatis之XML详解

文章目录 &#x1f38d;配置数据库连接和MyBatis&#x1f340;写持久层代码&#x1f338;添加mapper接口&#x1f338;添加UserInfoXMLMapper.xml&#x1f338;单元测试 &#x1f332;CRUD&#x1f338;增(Insert)&#x1f338;删(Delete)&#x1f338;改(Update)&#x1f338;…

CMake:静态库链接其他动态库或静态库(九)

1、项目结构 对于下面这样一个项目 把calc模块做成静态或者动态库把sort模块做成静态库然后再sort模块中的*.cpp调用calc模块生成的库即可&#xff08;这样就制作了一个静态库引用动态或者静态库&#xff09;test模块用于测试sort模块中的内容 . ├── calc │ ├── ad…

ThreeJS:本地部署官网文档与案例

部署方式 部署之前请确保已经配置好node.js环境。 1. 下载ThreeJS源码 ThreeJS的GitHub地址&#xff1a;GitHub - mrdoob/three.js: JavaScript 3D Library.&#xff0c;可以简单查看ThreeJS当前版本&#xff1a;r164&#xff0c; 我们可以选择对应的版本&#xff08;此处为r1…

【跟马少平老师学AI】-【神经网络是怎么实现的】(七-2)word2vec模型

一句话归纳&#xff1a; 1&#xff09;CBOW模型&#xff1a; 2c个向量是相加&#xff0c;而不是拼接。 2&#xff09;CBOW模型中的哈夫曼树&#xff1a; 从root开始&#xff0c;向左为1&#xff0c;向右为0。叶子结点对应词有中的一个词。每个词对应唯一的编码。词编码不等长。…

计算机等级考试2级(Python)知识点整理

计算机等级考试2级&#xff08;Python&#xff09;知识点整理 1.基础知识点&#xff08;记忆、理解&#xff09; 第1讲Python概述 01. 源代码 02. 目标代码 03. 编译和解释 04. 程序的基本编写方法 第2讲 Python语言基础&#xff08;一&#xff09; 01. 用缩进表示代码…

深入理解网络原理1

文章目录 前言一、网络初识1.1 IP地址1.2 端口号1.3 协议1.4 五元组1.5 协议分层 二、TCP/IP五层协议三、封装和分用四、客户端vs服务端4.1 交互模式4.2 常见的客户端服务端模型4.3 TCP和UDP差别 前言 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享…

前端基础学习html(1)

1.标题标签.h1,h2...h6 2.段落标签p 换行标签br 3.加粗strong(b) /倾斜em(i) /删除 del(s) /下划线ins(u) 4.盒子&#xff1a;div //一行一个 span//一行多个 5.img :src alt title width height border 图片src引用&#xff1a;相对路径 上级/同级/中级 绝对路径&#xff…

地图产业的困局与破局:高精地图“上车”难 轻量化渐成主流方案 | 最新快讯

《科创板日报》5月3日讯&#xff08;编辑 邱思雨&#xff09; 近期&#xff0c;特斯拉与百度的“绯闻”成为智驾、地图行业的焦点。 有媒体消息称&#xff0c;特斯拉将与百度地图独家深度定制车道级高辅地图。《科创板日报》记者也获悉&#xff0c;自5月1日起&#xff0c;百度…

【C语言实现贪吃蛇】(内含源码)

前言&#xff1a;首先在实现贪吃蛇小游戏之前&#xff0c;我们要先了解Win32 API的有关知识 1.Win32 API Windows这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外&#xff0c;它同时也是一个很大的服务中心&#xff0c;调佣这个中心的各种服务&#xff08;每一…

前端面试和一些建议

最近公司在招前端&#xff0c;我有跟着一起参与面试。我们主要负责面试的人&#xff0c;不会问那些什么闭包&#xff0c;原型链&#xff0c;他觉得那些东西在我们日常开发中用不到&#xff0c;问的基本都是一些工作中的问题。这些问题不是每次都问&#xff0c;但也就问这些了。…

基于Unity+Vue通信交互的WebGL项目实践

unity-webgl 是无法直接向vue项目进行通信的&#xff0c;需要一个中间者 jslib 文件 jslib当作中间者&#xff0c;unity与它通信&#xff0c;前端也与它通信&#xff0c;在此基础上三者之间进行了通信对接 看过很多例子&#xff1a;介绍的都不是很详细&#xff0c;不如自己写&…

(39)4.29数据结构(栈,队列和数组)栈

#include<stdlib.h> #include<stdio.h> #define MaxSize 10 #define Elemtype int 1.栈的基本概念 2.栈的基本操作 typedef struct { Elemtype data[MaxSize]; int top; }Sqstack;//初始化栈 void InitStack(Sqstack& S) { S.top -1; //初始化…

4G小车的公网直播推流

一直想做一个小车, 可以通过4G推流, 没想到现在很多云服务提供商, SRS云服务器已经可以一键搭建了. 硬件方面, 就是一个1126驮着一个3516, 1126负责4G连接, 转流到Intenet, 3516负责vi_venc_rtsp 思路如下, 我的1126的摄像头一直没能横过来, 所以就不用1126的摄像头了, 先用35…