维护真实时间:应对系统时间篡改的技巧

系统时间安全:构建防篡改的时间同步与监控体系 在分布式系统和网络安全领域,时间同步是确保系统一致性、数据完整性和安全协议有效性的基础技术。其核心原理通常基于网络时间协议(NTP)或精确时间协议(PTP),通过层级化的时间源体系,将权威时钟源的时间逐级分发至各个计算节点。这项技术的核心价值在于为事务排序、日志审计、证书验证和分布式协调提供统一、可信的时间基准,是金融交易、数据备份和身份认证等关键应用场景的基石。一旦系统时间被篡改或发生大幅偏移,将直接导致安全机制失效、数据混乱和业务逻辑错误。本文聚焦于**时间篡改防御**和**NTP监控**,深入探讨如何 阅读详情
AI摘要

本文讨论了在App开发中如何处理系统时间可能不准确的问题,介绍了两种方案:连网时获取网络时间并同步,以及断网时通过本地定时器维护真实时间。作者提供了Dart代码示例,并强调了在不同网络状态下的逻辑设计和注意事项。

引言

在App使用中,由于系统时间用户可以随意更改,在某些特殊情况下会导致获取到的系统时间不正确问题。本篇代码使用dart语言进行相关描述。

1.问题分析:
手机系统时间 ≠ 真实时间,当我们做一些需要对时间精度和准确性要求较高的软件时,如果只通过调用系统API,获取到的时间不一定是真实的,那么就需要我们单独去维护一个真实的时间,下面主要分析了连网情况下和断网情况下两种时间维护方案。

2.方案一:连网情况下获取网络时间:
既然连网了,从网络获取时间就行了,获取到的时间与本地保存的时间同步,当然响应数据有一定的延时,如果想要特别精确再单独加上响应时间就行了。
Dart代码示例如下:

///获取网络时间
  Future<DateTime?> _getNetworkTime() async {
    try {
      final response = await HttpUtil.getInstance().get(apiUrl);

      if (response.statusCode == 200) {
        final Map<String, dynamic> responseData = json.decode(response.data);
        final String dateTimeString = responseData['datetime'];
        final DateTime networkTime = DateTime.parse(dateTimeString).toLocal();
        return networkTime;
      } else {
        print('Handle the response error here');
        return null;
      }
    } catch (e) {
      print('Handle any exceptions that may occur  $e');
      return null;
    }
  }

3.方案二:断网情况下本地时间维护:(重点)
既然断网了,方案一就一点用没了,此时有两种方法获取时间,一种是调用系统api,一种是获取本地维护的时间,我们知道系统时间是可以修改的,所以你获取系统时间的话,得到的不一定是正确的时间,那么只能从本地我们自己维护的时间去拿,那么问题来了本地时间要怎么去维护呢?
我们可以在应用启动的时候起个定时器1秒钟循环一次,对本地时间进行累加,不受系统时间影响,前提是本地第一次保存是时间必须是真实的时间系统时间不可靠,那么就把第一次从网络上获取的时间去保存下来供后续使用。需要注意的是这种情况下难免会有误差!

time2 = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (!isSpite) {
        CacheUtil.saveRealTime(CacheUtil.getLastRealTime() + 1000);
      }
    });

上面的代码是定时器一秒钟循环一次,每次对上一次保存的时间进行累加,也就是我们自己维护的时间,这里的1000写死了,细微误差暂不考虑在内。
当然这只是开始,如果在你应用使用中突然断网了,并且系统时间还被修改了,上面方法还可以维护一个真实的时间,那么如果断网后,你的程序退出了,而且系统时间还被修改了,该去怎么去保证时间的真实性呢?

4.逻辑设计:
这里我使用的方法是,在上面saveRealTime 中我们每次保存的不单是真实时间,还保存的一个系统时间的毫秒数。
///保存一次真实时间及一次系统时间(两次时间不一定相同)

  static void saveRealTime(int timeMillis) {
    SpUtil.putInt('timeMillis', timeMillis);
    SpUtil.putInt('systemTimeMillis', DateTime.now().millisecondsSinceEpoch);
  }

当程序退出时,systemTimeMillis 保存了上次退出时的系统时间,当下次启动应用时,获取当前系统时间,与上次保存的系统时间之差就是这段空缺的时间段,然后继续与本地的真实时间进行累加以达到获取维护真实时间的目的。

if (currTime - CacheUtil.getLastSystemTime() > 2000) {
          //当前系统时间 大于上次保存的时间(断网退出app时 保存的一次时间)
          //此处有个问题,用于修改时间大于当前时间(此时不用考虑)
          isSpite = false;
          var timeDiff = currTime - CacheUtil.getLastSystemTime();
          CacheUtil.saveRealTime(CacheUtil.getLastRealTime() + timeDiff);
        }

上面方法只适用 系统时间被修改一次的情况,至于为什么要大于2000毫秒,是因为上面还有个一秒循环一次的定时器在维护时间,只有程序退出了这两数之差才可能大于2000,因为这两个定时器是并行的,为了避免小概率事件大于1000有时可能会有问题!
当用户在程序退出后再断网,然后修改系统时间,此时上述方法就无力回天了,只能禁用与时间相关的所有功能,待时间恢复正常(连网…)再恢复相关功能使用。

if (currTime - CacheUtil.getLastSystemTime() < 0) {
          //当前时间小于上次保存的时间,代表时间被恶意修改,禁用所有与时间相关的功能,
          // 直到连网或者修改系统时间大于当前时间
          isSpite = true;
        }

下面是完整代码示例:

import 'dart:async';
import 'dart:convert';

import '../../http/httpUtil.dart';
import '../cache.dart';

///
/// 此类内部维护一个真实时间,由于系统时间可被修改,所以系统时间仅供参考
///
/// 用来获取当前真实时间
///
const String apiUrl = 'https://worldtimeapi.org/api/ip';

class RealTimeUtil {
  late Timer time;
  late Timer time2;

  //是否可以使用系统时间
  bool canUseSystem = false;

  //时间是否被恶意篡改
  bool isSpite = false;

  // 使用静态变量_instance来存储单例实例
  static RealTimeUtil? _instance;

  // 私有构造函数,防止外部实例化
  RealTimeUtil._() {
    init();
  }

  // 工厂构造函数,用于返回单例实例
  factory RealTimeUtil() {
    // 如果实例尚未初始化,则创建一个新实例
    _instance ??= RealTimeUtil._();
    return _instance!;
  }

  void init() async {
    _task();
    time = Timer.periodic(const Duration(seconds: 10), (timer) {
      _task();
    });
    time2 = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (!isSpite) {
        CacheUtil.saveRealTime(CacheUtil.getLastRealTime() + 1000);
      }
    });
  }

  _task() {
    _getNetworkTime().then((DateTime? dateTime) {
      if (dateTime != null) {
        //获取网络时间成功
        isSpite = false;
        if ((dateTime.millisecondsSinceEpoch - DateTime.now().millisecondsSinceEpoch).abs() > 5000) {
          //网络时间大于系统时间5s 代表本地时间不正确, 5s是个阈值,视实际情况而定
          canUseSystem = false;
          CacheUtil.saveRealTime(dateTime.millisecondsSinceEpoch);
        } else {
          canUseSystem = true;
          CacheUtil.saveRealTime(DateTime.now().millisecondsSinceEpoch);
        }
      } else {
        //获取网络时间失败
        var currTime = DateTime.now().millisecondsSinceEpoch;

        print(
            'test 获取网络时间失败  currTime  = ${currTime - CacheUtil.getLastSystemTime()}  isSpite = $isSpite');

        if (currTime - CacheUtil.getLastSystemTime() > 2000) {
          //当前系统时间 大于上次保存的时间(断网退出app时 保存的一次时间)
          //此处有个问题,用于修改时间大于当前时间(此时不用考虑)
          isSpite = false;
          var timeDiff = currTime - CacheUtil.getLastSystemTime();
          CacheUtil.saveRealTime(CacheUtil.getLastRealTime() + timeDiff);
        } else if (currTime - CacheUtil.getLastSystemTime() < 0) {
          //当前时间小于上次保存的时间,代表时间被恶意修改,禁用所有与时间相关的功能,
          // 直到连网或者修改系统时间大于当前时间
          isSpite = true;
        }
      }
    });
  }

  ///获取真实时间的唯一路径
  DateTime getRealTime() {
    int lastRealTimeMillis = CacheUtil.getLastRealTime();

    // 创建一个DateTime对象,需要将时间戳转换为DateTime
    DateTime realTime = DateTime.fromMillisecondsSinceEpoch(lastRealTimeMillis);
    return realTime;
  }

  ///获取网络时间
  Future<DateTime?> _getNetworkTime() async {
    try {
      final response = await HttpUtil.getInstance().get(apiUrl);

      if (response.statusCode == 200) {
        final Map<String, dynamic> responseData = json.decode(response.data);
        final String dateTimeString = responseData['datetime'];
        final DateTime networkTime = DateTime.parse(dateTimeString).toLocal();
        return networkTime;
      } else {
        print('Handle the response error here');
        return null;
      }
    } catch (e) {
      print('Handle any exceptions that may occur  $e');
      return null;
    }
  }
}

5.总结:
当然上述方法,是以系统时间为参考进行的补救措施,如果使用的是系统启动时间,而不是系统时间为参考,上面问题就迎刃而解了。这里没有尝试该方法,我主要是给大家提供一个思路,而且博主能力有限,很多细节可能未考虑在内,大家有好的方法也可以提出来,共同学习,一起进步。

SpringBoot API接口防篡改与防重放攻击实战:HMAC签名+时间戳Nonce方案 在Web服务与API开发中,接口安全是保障数据传输可靠性与业务逻辑正确性的基石。其核心原理在于通过密码学技术验证数据完整性,并通过请求标识保证操作唯一性,以此防御中间人篡改与恶意重放两大常见攻击。从技术价值看,这不仅是满足安全合规的基本要求,更是构建可信分布式系统的关键实践,能有效防止资产损失、数据错乱与资源耗尽。典型的应用场景包括支付交易、敏感操作接口、第三方API集成等对安全要求较高的领域。本文聚焦于在SpringBoot项目中落地这一机制,详细阐述了基于HMAC-SHA256的签名校验实现,以及结合时 阅读详情

相关推荐

单片机加密存储与固件防篡改机制研究

嵌入式系统是一种专用的计算机系统,它被设计用于执行特定的任务,广泛应用于各种设备和系统中。资源受限:嵌入式系统通常具有有限的计算能力、存储空间和功耗预算。例如,许多物联网传感器节点采用低功耗微控制器,其主频仅为几十兆赫兹,存储空间仅几百KB,这使得嵌入式系统在设计时必须考虑资源优化。实时性要求:许多嵌入式系统需要在规定的时间内完成特定的任务,如工业自动化控制系统中的实时数据采集与处理,医疗设备中的生命体征监测等,对实时性的要求极高。可靠性高。

qq_40552871的博客 842

软件时间限制的原理

这类软件一般都有时间段的限制,例如试用30天等。当过了共享软件的试用期后,就不予运行。只有向软件作者付费注册之后才能得到一个无时间限制的注册版本。这种保护的实现方式大致如下。

大浪淘沙 1万+

系统时间防改工具0.9b - 防止恶意篡改时间的防护软件

随着网络攻击手段的不断进化,传统的安全防护措施已经难以完全保障系统的时间安全。因此,专业工具的开发和应用成为了维护系统时间准确性的关键。本章节将对一款名为“系统时间防改工具0.9b”的功能进行详细介绍,帮助读者了解如何有效应对系统时间篡改攻击。“系统时间防改工具0.9b”采用模块化的架构设计,由核心防护模块、监控模块、校验模块和用户界面四个主要部分构成。核心防护模块负责时间的校验和防护,监控模块实时监测系统时间状态,校验模块定期或在事件触发时执行时间准确性检查,而用户界面则是用户与工具交互的平台。

weixin_33506815的博客 927

优快云的自动发布时间认证太低级了

已经习惯了在google doc上写文章,然后发布到csdn的blog上但是今天才发现居然csdn把我本机的设置时间作为我的发布时间。。。虽然正常人都是把本机时间与现实时间一致,但也存在我这样的异类的阿。。。害的我还以为publish功能不工作了。。。 最可笑的是 republish居然不能更新时间 于是只好 remove掉再重新publish过来。。。

K的小世界 840

Windows下用Caddy一键搞定LiveKit本地HTTPS部署(含自签名证书避坑指南)

本文详细介绍了在Windows本地开发环境中,如何利用Caddy服务器一键部署支持HTTPS和WSS的LiveKit实时通信服务。文章重点解决了自签名证书的生成与配置难题,提供了完整的避坑指南和防火墙设置,帮助开发者快速搭建安全的WebRTC测试环境,实现局域网内的实时音视频互动。

weixin_29274969的博客 580

均匀直线阵的常规波束形成matlab

常规波束形成概述 波束形成是将基阵各阵元输出进行一定的处理,从而形成基阵空间指向性的技术。一个波束形成器可以对空间某方位的信号有响应,而抑制其他方位的信号,所以又被称为空域滤波。一般分为常规波束形成(CBF)和自适应波束形成(ABF)。 常规波束形成较为基础,一般又可以根据实现的途径不同,分为时延波束形成和频移波束形成。 时延波束形成 在各阵元间添加时延使波束控制于不同方位的方法成为时延波束形成。设定一个目标方向,当信号来源方向在该目标方向时,响应最大;信号来源于其他方向时,响应较小。将这种响应大小

Xujing1143的博客 2万+

几招百试不爽的软件防破解技巧

<br /> 孰不知再好的盾也有茅可以刺破一样,世界上很多nb的软件用了好多nb的防破解技术,结果还是被强大的黑客一一攻破,那对于我们这样的小程序员或小公司来说,既然nb的技术没有用,我们也没有那nb的防破解技术,何不如化有形为无形,不去用技术问题解决软件的防破解。<br />  个人总结:软件防破解其实不是技术问题,而是一个社会工程学问题。<br />  现在就给大家几条在开发软件的过程中几招百试不爽的软件防破解技巧,这些非技术的技巧实现起来很容易,但是防破解的效果是大大的。<br />  1、试用版就是

joyinsoft的专栏 763

基于STM32的多路火灾报警系统设计

本文设计了一款基于STM32的多路火灾报警系统,利用多个传感器组合(如烟雾传感器、温度传感器等)进行数据采集与处理,精确判断火灾情况,并及时发出报警信号,保障生命与财产安全。本系统设计了一款基于STM32的多路火灾报警系统,通过结合烟雾传感器和温度传感器,提升了火灾检测的准确性和可靠性。未来,系统可以进一步集成更多传感器,如气体传感器、湿度传感器等,进一步提升火灾报警系统的智能化水平。本系统采用STM32F103单片机作为核心处理单元,结合烟雾传感器、温度传感器和报警模块,实现多通道火灾报警功能。

stm32d1219的博客 2028

Windows 10+防止系统时间被恶意篡改!

进入组策略设置后,依次找到:计算机配置→windows设置→安全设置→本地策略→用户权利分配。找到"更改系统时间",双击打开它的属性对话框。按WIN+R, 运行输入gpedit.msc,点击确认,进入组策略设置。系统重启好后,检查系统无法修改成功日期。到此禁止修改时间配置完成!

qq_35719898的博客 4152

基于Jira与Confluence的企业知识库AI助手构建实战

检索增强生成(RAG)技术通过结合信息检索与大型语言模型,有效解决了AI在专业领域知识不足的问题。其核心原理是将外部知识库(如企业文档)进行向量化存储,在用户提问时进行语义检索,并将相关上下文注入提示词中,从而生成精准、有据可依的回答。这一技术架构在工程实践中价值显著,它无需重新训练模型即可让AI掌握特定领域的专业知识,大幅提升了回答的准确性与实用性。典型的应用场景包括智能客服、企业内部知识问答以及代码辅助等。本文以开源项目`dev-kostiuk/jira-confluence-ai-context`为例

weixin_42520448的博客 366

uniCloud云存储进阶:七牛云扩展存储从开通、绑定域名到批量上传的完整实战

本文详细介绍了uniCloud云存储进阶实践,重点讲解如何通过七牛云扩展存储实现从开通、绑定域名到批量上传的完整流程。内容涵盖成本优势分析、域名备案方案、SSL证书配置、多文件并发上传控制等实战技巧,并提供可直接复用的代码示例,帮助开发者高效构建内容社区类应用。

weixin_26985923的博客 468

如何应对机器视觉软件中时间篡改与许可绕过的挑战?

本文探讨了机器视觉软件中时间篡改和许可绕过的问题,并介绍了加密锁技术如何防止这些行为。通过使用CodeMeter解决方案,企业能够有效保护软件资产,确保合法使用,提升市场竞争力。加密锁提供了多层次的保护机制,有效防止时间篡改和未经授权的使用,保障了软件的安全性和完整性。

加密狗专栏 1046

HarmonyOS逆向降级实战:从鸿蒙2.0回退至EMUI 10.1的完整路径解析

本文详细解析了从HarmonyOS 2.0逆向降级至EMUI 10.1的完整操作流程,涵盖必备工具准备、数据备份策略及阶梯式降级步骤。针对华为手机用户遇到的兼容性问题,提供HiSuite和HiSuite Proxy工具的具体使用方法,并分享降级失败应急处理与系统优化技巧,帮助用户安全高效完成系统回退。

weixin_27741699的博客 1888

系统时间防篡改:从NTP加固到应用层最佳实践

在分布式系统和网络安全领域,系统时间的准确性与一致性是保障业务稳定和数据安全的基础设施。其工作原理涉及硬件时钟、操作系统内核、网络时间协议等多个层级,任何环节的偏差都可能导致安全机制失效、数据一致性破坏等严重后果。从技术价值看,维护时间完整性对于分布式锁、事务排序、日志审计和证书验证等核心功能至关重要。应用场景广泛覆盖金融交易、云原生环境、数据库复制和监控告警系统。本文聚焦于时间篡改风险,深入探讨通过加固NTP配置、限制系统调用权限、采用单调时钟编程等工程实践,构建从预防、检测到恢复的完整防御体系,并特别针

weixin_34268843的博客 401

(秋招复习)一些SLAM基础

秋招复习--SLAM基础知识篇

weixin_45432823的博客 767

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

网站维护中的风险及应对策略

网站维护期间的风险是不可忽视的,但通过适当的应对策略,企业可以降低这些风险对业务和用户的影响。通过细致的规划和严格的保护措施,企业可以确保网站的维护期间是安全、高效和顺利的,最重要的还是要选择一家例如德迅云安全这种较为专业的网络安全服务商进行维护合作,可避免网站遭受不必要的影响损失。本文将探讨网站维护中可能面临的风险,并提供一些应对策略以降低这些风险对企业的影响。DDoS攻击的目的是使目标网站或网络过载,消耗其带宽、服务器资源和网络连接,导致服务不可用,从而剥夺合法用户对该网站或网络的正常访问。

Dexun_chuqi的博客 839

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

网络安全应急响应----8、网页篡改应急响应

文章目录一、网页篡改简介二、网页篡改检测技术1、外挂轮询技术2、核心内嵌技术3、事件触发技术三、网页篡改应急响应方法1、发生网页篡改2、隔离被感染的服务器/主机2.1、针对被篡改的网页2.2、针对未被篡改的网页3、排查业务系统3.1、异常端口、进程排查3.2、可疑文件排查3.3、可疑账号排查3.4、确认篡改时间3.5、日志排查3.6、网络流量排查4、恢复数据和业务四、网页篡改防御方法 一、网页篡改简介 网页篡改:即攻击者故意篡改网络上传送的报文,通常以入侵系统并篡改数据、劫持网络连接或插入数据等形式进行

七天 1万+

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

系统维护必备:树莓派更新指令异常的20种应对方案

树莓派更新系统的指令出错时,别急着重刷系统。从网络配置、源地址失效、apt缓存损坏,到SD卡读写错误、时间同步异常等常见原因,逐一排查更高效。结合树莓派更新系统的指令出错场景,提供可立即执行的终端命令与配置调整技巧,帮你快速恢复稳定更新流程。

weixin_42601134的博客 383

是否对Web应用的URL重写和防篡改策略进行了设置?

本文从url重写和安全防护两方面进行了详细的论述分析了采用url重写技术在应对网站安全问题上的可行性和重要性同时也探讨了常见的防篡改方法并提出了相应的防护措施相信通过合理有效的管理和应用这些技术我们可以更好地维护网站的安全性,为用户营造更安全的网络环境使用自动化管理工具多品牌异构防火墙统一管理多品牌、多型号防火墙统一管理;确保所有设备按同一标准配置,提升安全性;集中管理简化部署,减少重复操作;统一流程减少配置差异和人为疏漏;快速定位问题,提升响应速度;集中管理减少人力和时间投入,优化成本。

ZOMO的博客 1144

数据篡改是一种被低估的威胁——准备好备份

有了不可变的备份,您就可以应对所有这些了。

网络研究观 4605

AudioSeal Pixel Studio实战落地:政务热线录音版权管理与篡改追溯系统

本文介绍了如何在星图GPU平台上自动化部署🌊 专业级音频水印加印AudioSeal Pixel Studio镜像,构建政务热线录音版权管理与篡改追溯系统。该方案的核心应用场景是为海量政务热线录音嵌入不可见的“数字身份证”,确保其原始性与完整性,有效应对AI伪造和恶意篡改,实现录音来源的快速追溯与验证。

weixin_36122351的博客 29

毕设设计|计算机毕业设计|大数据深度学习|基于UNet-VGG提取PS图片篡改检测

在数字化信息时代,图像作为一种重要的信息载体,广泛应用于新闻媒体、司法取证、医学影像、金融交易、社交媒体等众多领域,其真实性和可靠性至关重要。随着计算机技术和图像处理软件的飞速发展,如 Adobe Photoshop 等专业图像编辑工具以及各种便捷的手机修图应用的普及,图像篡改变得极为容易,普通用户甚至无需专业知识就能对图像进行复杂的修改。恶意篡改后的图像通过网络快速传播,可能会误导公众认知,干扰舆论导向,例如在新闻报道中传播虚假的事件现场图片,可能引发公众的恐慌和误解;在司法领域,伪造的图像证据可能导致错

2201_75937987的博客 1377

账号风控突破:云手机设备指纹篡改检测与反制技术解析

技术核心:需实现硬件参数动态化、行为模式非线性化、网络特征隐匿化的三维防御体系。成本与效率平衡:采用混合云架构(自建ARM服务器+公有云手机)降低30%运营成本。合规红线:避免恶意刷量、欺诈等行为,优先选择支持GDPR/CCPA的代理服务商。

2501_90930584的博客 3984

人肉区块链:用群体记忆对抗AI篡改

摘要:随着生成式AI渗透软件测试领域,测试数据面临系统性篡改风险。AI可伪造测试日志、性能指标甚至视频证据,传统验证手段失效。文章提出"人肉区块链"防御方案,通过分布式团队记忆、共识机制和社会性锚点构建抗篡改体系。该方案将测试流程分为规划、执行和闭环三阶段,采用独立记录、交叉核对和群体共识等方法,在保持效率的同时提升可信度。未来测试工程师角色将向"数字真相架构师"演进,通过人机协作维护软件质量的可信基础。(149字)

2501_94449023的博客 185
上一篇: 详解十大经典排序算法(六):快速排序(QuickSort)
下一篇: 关于Android studio新版本和NEW UI显示返回按钮的设置
_蓝橙
博客等级 码龄7年 1179粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值