我正在寻找一种可靠的获取时间的方式。它不能被篡改并且需要离线工作。因此不能使用网络时间,也不能在设置中使用用户时间,也不能使用自上次重启以来的BSD运行时间。我想知道GPS是否可以使用原子钟来工作,从而访问该信息。
谢谢
我正在寻找一种可靠的获取时间的方式。它不能被篡改并且需要离线工作。因此不能使用网络时间,也不能在设置中使用用户时间,也不能使用自上次重启以来的BSD运行时间。我想知道GPS是否可以使用原子钟来工作,从而访问该信息。
谢谢
这段代码可以获取GPS时间:
#import <CoreLocation/CoreLocation.h>
CLLocation* gps = [[CLLocation alloc]
initWithLatitude:(CLLocationDegrees) 0.0
longitude:(CLLocationDegrees) 0.0];
NSDate* now = gps.timestamp;
然而它似乎不是防篡改的。
我在iPhone 4(iOS 6.1)上使用飞行模式尝试了这段代码,即使这时候也能正确给出时间。但不幸的是,这个时间似乎随着系统时钟的变化而变化。真糟糕。
有趣的是,我发现(仍处于飞行模式),如果您篡改系统时钟(在将“设置自动”切换到 off
后),然后将“设置自动”重新切换为 on
,该设备会毫不费力地恢复实际(原始)时间。 即使在循环手机电源之后,此方法也有效。因此,似乎设备内部维护了类似于防篡改时间的东西。但是如何访问它呢?
P.S. 2010年关于此的讨论。倒数第二条评论的作者曾尝试在避难所中进行此操作:因此可以确定该手机并未从任何外部来源获得原始时间。
发现了几篇关于另一种时间测量方式的帖子(这里,这里和这里):系统内核启动时间。可以通过类似以下的调用来访问它:sysctlbyname("kern.boottime", &boottime, &size, NULL, 0);
。不幸的是,即使没有重新启动,它也会随着用户调整的日期和时间而改变。另一个函数gettimeofday()
同样依赖于用户定义的时间。
gps.timestamp
返回的时间与 [NSDate date]
完全相同。 - kelinNSDate及其CF对应项都基于用户可控时间,因此不是防篡改的。
据我所知,没有直接获取GPS时间或运营商时间的开放API。但是,您可以检查mach_absolute_time以获取自上次启动以来未经篡改的时间,并可能将其用于至少了解自应用程序唤醒以来经过了多长时间(而不会在应用程序运行时潜在地被篡改)。
mach_absolute_time取决于设备的处理器。它返回自上次重启(也称为正常运行时间)以来的滴答数。为了以人类可读的形式获得它,您必须通过mach_timebase_info(一种比率)的结果进行修改,它将返回十亿分之一秒(或纳秒)。为了使其更易用,我使用以下类似的函数:
#include <mach/mach_time.h>
int getUptimeInMilliseconds()
{
static const int64_t kOneMillion = 1000 * 1000;
static mach_timebase_info_data_t s_timebase_info;
if (s_timebase_info.denom == 0) {
(void) mach_timebase_info(&s_timebase_info);
}
// mach_absolute_time() returns billionth of seconds,
// so divide by one million to get milliseconds
return (int)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
}
这会获取当前日期和时间:
NSDate *now = [NSDate date];
CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
返回与普通UNIX自纪元以来的秒时间戳相当的CoreFoundation。
[NSDate date]
返回的时间可以被用户更改。 - kelin时间测量的黄金标准是美国和全球各个政府时间观测站。它们提供原子时间,这在全球范围内使用。苹果应该使用这个。如果他们想要与手机塔同步,应该有一个备用的内部时间。如果塔或GPS系统发生故障,所有人都会留下错误的时间。