#objective-c #xcode #facebook #random
#objective-c #xcode #Facebook #Случайный
Вопрос:
я создаю приложение, которое показывает случайное изображение профиля Facebook, но не знаю, как сделать идентификатор профиля случайным числом. Очевидно, я могу изменить его случайным образом в коде, но он должен быть случайным. Это вторая строка NS, которая мне нужна, чтобы быть случайной. Любая помощь будет высоко оценена!
- (IBAction) nextImagePush {
NSString *prefix = @"http://graph.facebook.com/";
NSString *profileId = @"517418970";
NSString *suffix = @"/picture?type=large";
NSString* url= [NSString stringWithFormat:@"%@%@%@", prefix, profileId, suffix];
UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:url]]];
[imageView setImage:img];
Комментарии:
1. Если я помогу вам, вы исключите мой идентификатор профиля в своем приложении?
2. Зачем вам это нужно?
Ответ №1:
NSString *profileId = [NSString stringWithFormat:@"%0.10u", arc4random()];
NSLog(@"profileId: %@", profileId);
Вывод NSLog:
profileId: 1375609947
Обновлено для использования arc4random_uniform
.
Для несмещенного целого числа в пределах диапазона:
(u_int32_t)randomInRangeLo:(u_int32_t)loBound toHi:(u_int32_t)hiBound {
int32_t range = hiBound - loBound 1;
u_int32_t random = arc4random_uniform(range);
return loBound random;
}
NSString *profileId = [NSString stringWithFormat:@"%0.9u", [AppDelegate randomInRangeLo:0 toHi:999999999]];
NSLog(@"profileId: %@", profileId);
Вывод NSLog:
profileId: 2500425665
Для использования SecRandomCopyBytes потребуется включить файл заголовка:
#import <Security/SecRandom.h>
и структура:
Security.framework.
Еще лучше для версий OS X > = 10.7 или iOS> = 4.3 использовать arc4random_uniform
(u_int32_t)randomInRangeLo:(u_int32_t)loBound toHi:(u_int32_t)hiBound
{
int32_t range = hiBound - loBound 1;
return loBound arc4random_uniform(range);
}
Комментарии:
1. Это отлично работает, хотя иногда возвращает минус-числа, например -236716805 есть ли какой-либо способ изменить этот код, чтобы возвращать только положительные числа?
2. -1. Никогда не используйте arc4random(), если вы не понимаете предостережений (а именно, он задокументирован как небезопасный для потоков, если вы не выполняете собственную блокировку, поэтому он обычно небезопасен для использования в библиотечном коде). Возвращаемый тип также
u_int32_t
является тем, почему он, по-видимому, выдает отрицательные числа при форматировании с помощью «%d» (что более важно, неопределенное поведение), и вызовabs()
strictly также приводит к неопределенному поведению.3.
rand_r()
предположительно потокобезопасен и безопасен для сигналов. Тогда естьSecRandomCopyBytes()
(который, вероятно, выполняет открытие / чтение / закрытие/dev/urandom
) или Mersenne Twister (для которого существует множество библиотек). RC4 не особенно быстр и криптографически слаб, что делает его плохим выбором для большинства применений.4. От Man: rand_r() «эта функция будет слабым генератором псевдослучайных чисел», и это зависит от случайного начального числа, его не следует использовать. SecRandomCopyBytes() — отличный выбор, является ли он потокобезопасным? Mersenne Twister и RC4 действительно выходят далеко за рамки этого вопроса / использования, и безопасность потоков зависит от конкретной реализации.
5.
SecRandomCopyBytes()
почти наверняка здесь тоже неправильно использовать (с каких пор для выбора «случайного» профиля facebook требуется безопасный генератор случайных чисел?), И он будет намного медленнее, а чтение произвольных байтов в uint32_t может быть неопределенным поведением, и форматировать u_int32_t по-прежнему небезопаснос %d и, вероятно, выдаст предупреждение в будущих компиляторах (возможно, оно уже выдаст предупреждение с помощью интерфейса Clang).
Ответ №2:
для генерации случайных чисел с фиксированным интервалом вы можете использовать arc4random()%x. x представляет максимальное число, которое вы хотите получить. Конечно, есть и другие способы, но этот отлично работает.
Комментарии:
1. Будет смещение в сторону меньших чисел, но для x, во много раз меньшего, чем 2 ^ 32, смещение довольно мало.
Ответ №3:
Легко выбрать случайное целое число с помощью такой функции, как rand(3)
, random(3)
, или arc4random(3)
, а затем использовать [NSString stringWithFormat:]
для преобразования его в строку с помощью спецификатора %u
формата.
Гораздо сложнее убедиться, что выбранное вами целое число соответствует действительному идентификатору пользователя Facebook:
- Документирует ли Facebook где-нибудь возможные действительные идентификаторы?
- Всегда ли они находятся в определенном диапазоне?
- Все ли идентификаторы в этом диапазоне действительны?
- Есть ли какой-либо способ запросить диапазон допустимых идентификаторов?
Если ответ на все эти вопросы «да», то вы можете это сделать, в противном случае это будет практически невозможно, если Facebook не предоставит API для того, что вы хотите, что, я думаю, маловероятно.
Комментарии:
1. Я не уверен в конкретном формате для профилей, но, только что добавив часть приведенного выше кода, кажется, что при просмотре консоли отладчика число с — перед ним не возвращает изображение, а без него, например: 2011-10-03 22:33:36.096 FacebookPictures[12687:207] ProfileID: 1159988985 2011-10-03 22:33:36.623 Фотографии FacebookPictures[12687:207] ProfileID: 1159988985 2011-10-03 22:33:40.213 Фотографии FacebookPictures[12687:207] ProfileID: -1040500245 2011-10-03 22:33:40,615 Фотографии FacebookPictures[12687:207] ProfileID : -1040500245
2. Как я мог бы сделать так, чтобы, если перед возвращаемым числом действительно было -, это число пропускалось до тех пор, пока не будет сгенерировано одно без -?
3. Никогда не используйте rand() или random(), всегда используйте arc4random().
4. Да, я использовал код, который вы указали выше, но почти половина чисел отрицательные, есть ли способ сделать их просто положительными числами?
5. @Harry: используйте указанный
%u
формат, чтобы отформатировать его как целое число без знака вместо целого числа со знаком.